2016-07-01 10 views
-1

Ich verwendete LINQ zum Verketten mehrerer Zeilen in einzelne Zeile. Ich habe Probleme bei der Verwendung der dynamischen Suchseite.Dynamische Suche und Linq, um eine durch Komma getrennte Zeichenfolge zurückzugeben

User Hobby 
-------------- 
Bob Football 
Bob Golf 
Bob Basketball 
Sue Sleeping 
Sue Drinking 

zu

User Hobby 
-------------- 
Bob Football, Golf, Tennis 
Sue Sleeping, Drinking 

mit

var users = new[] 
{ 
    new { User="Bob", Hobby="Football" }, 
    new { User="Bob", Hobby="Golf" }, 
    new { User="Bob", Hobby="Tennis" }, 
    new { User="Sue", Hobby="Sleeping" }, 
    new { User="Sue", Hobby="Drinking" }, 
}; 

var userList = users.ToList(); 

var result1 = (from user in users 
       group user by user.User into groupedUserList 
       select new { 
        user = groupedUserList.Key, 
        hobby = groupedUserList.Select(x => x.Hobby).Aggregate((a, b) => (a + ", " + b)) 
       }); 

var result2 = (from groupeduser in ug 
select new{ groupeduser.user, hobby =string.Join(",", groupeduser.hobby)}); 

Wenn ich mit Hobby Suchfeld

mit result1 = result1.Where hinzufügen (t => t.Hobby. Enthält ("Ball"));

es Fehler werfen ---> Aggregate nicht

unterstützt

mit result2 = result2.Where (t => t.Hobby.Contains ("Kugel"));

es werfen System.String Join (System.String, System.String []) nicht auf SQL unterstützt übersetzen

+0

in 'von groupeduser in ug', was' ug'? – currarpickt

+0

Wenn Sie die Funktion Contains in linq in sql konvertieren möchten, können Sie 'users.Where verwenden (s => SqlMethods.Like (s.Hobby,"% {0}% "))' –

+0

tut 'result1.ToList(). Wo (t => t.Hobby.Kontakt ("Ball")); 'Arbeit? – Nsevens

Antwort

1

, die nur in Linq-To-Objects unterstützt wird, so dass Sie AsEnumerable oder ToList verwenden können:

var userGroups = from user in users 
       group user by user.User into groupedUserList 
       select new { 
        user = groupedUserList.Key, 
        userHobbies = groupedUserList.Select(x => x.Hobby) 
       }; 

foreach(var grp in userGroups.AsEnumerable()) 
    Console.WriteLine("user:{0} hobbies:{1}" 
     , grp.user 
     , String.Join(",", grp.userHobbies)); 

Wenn Sie möchten, um das Ergebnis filtern Sie das tun sollten, bevor Sie es in den Speicher geladen werden (zB mit ToList). So verwenden Where zuerst:

var usersGroupsWithBallHobbies = userGroups 
    .Where(g => g.userHobbies.Any(hobby => hobby.Contains("ball"))); 
foreach(var grp in usersGroupsWithBallHobbies.AsEnumerable()) 
    ... 

Diese Any + String.Contains sollte auch funktionieren in Linq-To-Entities (> = .NET 4)

+0

Nach ToList erhalten alle Daten aus der Datenbank und das Hauptproblem ist Filter thre Ergebnis nach result1 und result2 mit enthält Methode für Hobbys. @ Tim-schmelter – stackCoder

+0

@stackCoder: bearbeitet meine Antwort, um Ihnen zu zeigen, wie man für "Ball" -Substrings filtert –

0
var result = from user in users 
     group user by user.User into groupedUserList 
     select new { User = groupedUserList.Key, 
         Hobby = string.Join(", ", 
          groupedUserList.Select(item => item.Hobby).ToList()) }; 
0
var groupedByUser = users.GroupBy(u => u.User) 
         .Select(g => new { User = g.Key, Hobbies = String.Join(", ", g.Select(u => u.Hobby)) }) 
         .ToList(); 
0

Sie sollten Ihre "SQL-supported" Anforderung zuerst wie das Abrufen Ihrer Daten durchführen gruppiert nach Hobbys mit Ihrem where Klausel, wie folgt aus:

var result1 = (from user in users 
       where user.Hobby.Contains("Ball") 
       group user by user.User); 

Dann Sie die Daten in den Speicher laden mit ToList() und die Verkettung von Hobbys, wie dies auszuführen:

var result2 = result1 
    .ToList() 
    .Select(x => new { 
     User = x.Key, 
     Hobbies = string.Join(",", x.Select(pair => pair.Hobby)) 
    }); 

Fazit:

  • result1 enthält Ihre Linq-to-Sql Abfrage.
  • result2 enthält Ihre In-Memory Abfrage, es ist Ihr Endergebnis.
+0

Ich habe kein Problem für das Ergebnis-Set. Das Hauptproblem ist Filter thre Ergebnis nach result1 und result2 mit enthält Methode für Hobbies @ nverinaud – stackCoder

+0

Warum möchten Sie beitreten die Hobbys vor der Verwendung enthalten? Wenn Sie eine bestimmte Spalte in Ihrer Datenbank haben, ist es effizienter, wo in dieser Spalte dann die Gruppe bis dann die Join! – nverinaud

+0

Die Ausgabe wird für "Ball" Bob => Fußball nur wenn ich es tue wo auf dieser Spalte vor beitreten nicht Fußball, Golf, Tennis @nverinaud – stackCoder

0
var hobbySearchKey = "ball"; 

users 
    .GroupBy(_ => _.User, _ => _.Hobby) // group users with hobbies 
    .Where(_ => _.Any(hobby => hobby.Contains(hobbySearchKey))) // filter only users whose hobbies contain a search key 
    .Select(_ => new { User = _.Key, Hobbies = string.Join(",", _)}); // concatenate hobbies 

MSDN auf Any LINQ to SQL

MSDN Blogs auf string.Contains

+0

Die Ausgabe wird für Bob => F ootball nur nicht Fußball, Golf, Tennis @ andriy-tolstoy – stackCoder

+0

@stackCoder - meine Schuld. Natürlich muss es zuerst gruppiert werden. Ich habe die Abfrage entsprechend bearbeitet. –

+0

Bitte bearbeiten Sie mit mehr Informationen. Code-only und "try this" Antworten werden abgeraten, da sie keine durchsuchbaren Inhalte enthalten und nicht erklären, warum jemand "das versuchen sollte". Wir bemühen uns, eine Ressource für Wissen zu sein. –