2013-04-24 9 views
9

Czy mimo to zrobić kwerendę linq2sql robi coś podobnego do tego:Case niewrażliwy grupa na wielu kolumnach

var result = source.GroupBy(a => new { a.Column1, a.Column2 }); 

lub

var result = from s in source 
      group s by new { s.Column1, s.Column2 } into c 
      select new { Column1 = c.Key.Column1, Column2 = c.Key.Column2 }; 

ale ignorowanie przypadek zawartości zgrupowanych kolumn ?

+0

to nie działa? 'a => {Column1 = a.Column1.ToLower(), Column2 = a.Column2.ToLower()}' –

Odpowiedz

18

Możesz przekazać StringComparer.InvariantCultureIgnoreCase do metody rozszerzającej GroupBy.

var result = source.GroupBy(a => new { a.Column1, a.Column2 }, 
       StringComparer.InvariantCultureIgnoreCase); 

Albo można użyć ToUpperInvariant na każdym polu jak sugeruje Hamlet Hakobyan w komentarzu. Zaleca się raczej ToUpperInvariant lub niż ToLower lub , ponieważ jest zoptymalizowany do celów programowego porównania.

+6

'StringComparer' nie może porównywać instancji typów anonimowych, tylko łańcuchów. Potrzebna jest nowa implementacja porównywania (zobacz odpowiedź Bona B) –

+0

@DiegoMijelshon, jeśli 'Column1' i' Column2' to typ 'string', następnie' GroupBy (a => a.Column1 + a.Column2, StringComparer.InvariantCultureIgnoreCase) powinien zadziałać – fubo

5

nie mogłem dostać rozwiązanie NaveenBhat do pracy, otrzymuję błąd kompilacji:

The type arguments for method 'System.Linq.Enumerable.GroupBy(System.Collections.Generic.IEnumerable, System.Func, System.Collections.Generic.IEqualityComparer)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

aby to działało, znalazłem to najprostszy i klarowne zdefiniowanie nowej klasy do przechowywania moich kolumn klucza (GroupKey) , następnie oddzielna klasa, która implementuje IEqualityComparer (KeyComparer). Mogę wtedy zadzwonić

var result= source.GroupBy(r => new GroupKey(r), new KeyComparer()); 

klasie KeyComparer ma porównania ciągów z comparer InvariantCultureIgnoreCase, więc uznanie dla NaveenBhat dla wskazujące mnie we właściwym kierunku.

Uproszczone wersje moich klas:

private class GroupKey 
{ 
    public string Column1{ get; set; } 
    public string Column2{ get; set; } 

    public GroupKey(SourceObject r) { 
     this.Column1 = r.Column1; 
     this.Column2 = r.Column2; 
    } 
} 

private class KeyComparer: IEqualityComparer<GroupKey> 
{ 

    bool IEqualityComparer<GroupKey>.Equals(GroupKey x, GroupKey y) 
    { 
     if (!x.Column1.Equals(y.Column1,StringComparer.InvariantCultureIgnoreCase) return false; 
     if (!x.Column2.Equals(y.Column2,StringComparer.InvariantCultureIgnoreCase) return false; 
     return true; 
     //my actual code is more complex than this, more columns to compare 
     //and handles null strings, but you get the idea. 
    } 

    int IEqualityComparer<GroupKey>.GetHashCode(GroupKey obj) 
    { 
     return 0.GetHashCode() ; // forces calling Equals 
     //Note, it would be more efficient to do something like 
     //string hcode = Column1.ToLower() + Column2.ToLower(); 
     //return hcode.GetHashCode(); 
     //but my object is more complex than this simplified example 

    } 
} 
+0

Czy na pewno nie wpisałeś po prostu 'StringComparison.InvariantCultureIgnoreCase' (który jest enumem) zamiast' StringComparer.InvariantCultureIgnoreCase' (która jest klasą)? –

+0

Masz rację, @dav_i, to jest źródło "nie można przekonwertować z" System.StringComparison "..." otrzymałem błąd. Jednak nawet gdy nie popełnię tego błędu, został zgłoszony inny błąd kompilacji. Zaktualizowałem swoją odpowiedź, aby odzwierciedlić napotkany problem i uzasadnienie tego rozwiązania. Dzięki! –

1

miałem ten sam problem grupowania przez wartości obiektów DataRow z tabeli, ale po prostu stosować .ToString() na obiekcie DataRow ominąć kompilatora wydanie, np

MyTable.AsEnumerable().GroupBy(
    dataRow => dataRow["Value"].ToString(), 
    StringComparer.InvariantCultureIgnoreCase) 

zamiast

MyTable.AsEnumerable().GroupBy(
    dataRow => dataRow["Value"], 
    StringComparer.InvariantCultureIgnoreCase) 
Powiązane problemy