Benutzer mit den meisten Antworten
Linq und Distinct()

Frage
-
Hallo! Ich habe eine Frage zu LINQ.
Ich habe ein ObjectContext (RIA, DomainService, generiert aus einem
Model im Web-Project), weches mir ein ObjectSet<PersonView> liefert.
Eine PersonView besteht aus Daten einer Person (z.B. Lastname,
Firstname).
Es kann vorkommen, dass die Kombination aus Lastname und Firstname
mehrmmals auftaucht, und so auch im OjectSet mehrmals auftaucht. Aber
ich möchte, dass die Methode "GetPersonViewByName" diese Kombination
nur einmal liefert (distinct).So etwas hilft aber nicht:
public IQueryable<PersonView> GetPersonViewByName(string part)
{
return (from item in this.ObjectContext.PersonView
where item.Lastname.StartsWith(part)
|| item.Lastname.EndsWith(part)
|| item.Firstname.StartsWith(part)
|| item.Firstname.EndsWith(part)
select item).Distinct();
}Okay, klar. Ich vergleiche auch die von mir erstelten Objekte, also
muss ich einen "EqualityComparer" schreiben.public class Equaler : IEqualityComparer<AllowanceView>
{
public bool Equals(PersonView x, PersonView y)
{
if (Object.ReferenceEquals(x, y))
return true;
if (Object.ReferenceEquals(x, null) ||
Object.ReferenceEquals(y, null))
return false;
return x.Partnernr == y.Partnernr;
}public int GetHashCode(PersonView x)
{
if (Object.ReferenceEquals(x, null))
return 0;
return x.GetHashCode();
}}
Ich verwende dies Klasse dann so:
public IQueryable<PersonView> GetPersonViewByName(string part)
{
return (from item in this.ObjectContext.PersonView
where item.Lastname.StartsWith(part)
|| item.Lastname.EndsWith(part)
|| item.Firstname.StartsWith(part)
|| item.Firstname.EndsWith(part)
select item).Distinct(new Equaler());
}Aber auch jetzt ist das ergenis nicht distinct.
Auch in diesem Falle nicht:public IQueryable<PersonView> GetPersonViewByName(string part)
{
return (from item in
this.ObjectContext.PersonView.Distinct(new Equaler)
where item.Lastname.StartsWith(part)
|| item.Lastname.EndsWith(part)
|| item.Firstname.StartsWith(part)
|| item.Firstname.EndsWith(part)
select item);
}Was mache ich falsch? Ist der EqualityComparer nicht richtig
geschrieben?Danke für die Hilfe!
Antworten
-
Hallo D.,
Linq to Entities hat da mehrere Möglichkeiten. Hier zwei davon:
1. Wenn Du nur die Kombination zweier Felder ausschließen möchtest:
var query1 = (from c in northwindEntities.Customers select new {c.City, c.Country}).Distinct();
2. Wenn Du auch anderen Felder zurückgeben möchtest:
var query2 = (from c in northwindEntities.Customers group c by new {c.City, c.Country} into g select g.FirstOrDefault());
Gewusst wie: Entfernen doppelter Elemente aus LINQ to Entities-Abfrageergebnissen:
http://msdn.microsoft.com/de-de/library/cc716801.aspxGruß
Marcel- Als Antwort vorgeschlagen Pawel Warmuth Samstag, 15. Januar 2011 12:21
- Als Antwort markiert Robert BreitenhoferModerator Mittwoch, 19. Januar 2011 07:29
-
Hallo D.,
hier ein paar Lösungs-Ansätze und Hinweise:
[Implementing a DISTINCT clause in LINQ, for your objects « Techkn0w]
http://techkn0w.wordpress.com/2010/06/09/implementing-a-distinct-clause-in-linq-for-your-objects/[c# - Distinct not working with LINQ to Objects - Stack Overflow]
http://stackoverflow.com/questions/1365748/distinct-not-working-with-linq-to-objects
[c# - LINQ Get Distinct values and fill LIST - Stack Overflow]
http://stackoverflow.com/questions/1786770/linq-get-distinct-values-and-fill-list[LINQ Farm: Using Distinct and Avoiding Lambdas - Charlie Calvert's Community Blog - Site Home - MSDN Blogs]
http://blogs.msdn.com/b/charlie/archive/2006/11/19/linq-farm-group-and-distinct.aspx[Implement IEquatable to Power Up LINQ Distinct Queries]
http://www.eggheadcafe.com/sample-code/LINQ/0673e72e-e8e2-459e-bae4-7e0126487093/implement-iequatable-to-power-up-linq-distinct-queries.aspx
ciao Frank- Als Antwort vorgeschlagen Pawel Warmuth Samstag, 15. Januar 2011 12:21
- Als Antwort markiert Robert BreitenhoferModerator Mittwoch, 19. Januar 2011 07:29
Alle Antworten
-
Am 13.01.2011 19:31, schrieb Dulcine2008:
Es kann vorkommen, dass die Kombination aus Lastname und Firstname
mehrmmals auftaucht, Aber ich möchte, dass die Methode diese Kombination nur einmal liefert (distinct).public IQueryable<PersonView> GetPersonViewByName(string part)
{
return (from item in this.ObjectContext.PersonView
where item.Lastname.StartsWith(part)
|| item.Lastname.EndsWith(part)
|| item.Firstname.StartsWith(part)
|| item.Firstname.EndsWith(part)
select item).Distinct();
}Okay, klar. Ich vergleiche auch die von mir erstelten Objekte, also
muss ich einen "EqualityComparer" schreiben.public class Equaler : IEqualityComparer<AllowanceView>
{
public bool Equals(PersonView x, PersonView y)
{
if (Object.ReferenceEquals(x, y))
return true;
if (Object.ReferenceEquals(x, null) ||
Object.ReferenceEquals(y, null))
return false;
return x.Partnernr == y.Partnernr;
}Du willst ja mehrfache Kombinationen von Lastname und Firstname
ausschließen, tatsächlich sortiert Du aber nur Mehrfach-Kombinationen
von Partnernr aus.Die letzte Zeile im IEqualityComparer sollte daher lauten:
bool Equals (...) { //... //alt: return x.Partnernr == y.Partnernr; return string.Compare(x.Lastname, y.Lastname) == 0 && string.Compare(x.Firstname, y.Firstname ) == 0; }
evtl noch case-unsensitiv machen.
Christoph
-
Hallo D.,
Linq to Entities hat da mehrere Möglichkeiten. Hier zwei davon:
1. Wenn Du nur die Kombination zweier Felder ausschließen möchtest:
var query1 = (from c in northwindEntities.Customers select new {c.City, c.Country}).Distinct();
2. Wenn Du auch anderen Felder zurückgeben möchtest:
var query2 = (from c in northwindEntities.Customers group c by new {c.City, c.Country} into g select g.FirstOrDefault());
Gewusst wie: Entfernen doppelter Elemente aus LINQ to Entities-Abfrageergebnissen:
http://msdn.microsoft.com/de-de/library/cc716801.aspxGruß
Marcel- Als Antwort vorgeschlagen Pawel Warmuth Samstag, 15. Januar 2011 12:21
- Als Antwort markiert Robert BreitenhoferModerator Mittwoch, 19. Januar 2011 07:29
-
Hallo D.,
hier ein paar Lösungs-Ansätze und Hinweise:
[Implementing a DISTINCT clause in LINQ, for your objects « Techkn0w]
http://techkn0w.wordpress.com/2010/06/09/implementing-a-distinct-clause-in-linq-for-your-objects/[c# - Distinct not working with LINQ to Objects - Stack Overflow]
http://stackoverflow.com/questions/1365748/distinct-not-working-with-linq-to-objects
[c# - LINQ Get Distinct values and fill LIST - Stack Overflow]
http://stackoverflow.com/questions/1786770/linq-get-distinct-values-and-fill-list[LINQ Farm: Using Distinct and Avoiding Lambdas - Charlie Calvert's Community Blog - Site Home - MSDN Blogs]
http://blogs.msdn.com/b/charlie/archive/2006/11/19/linq-farm-group-and-distinct.aspx[Implement IEquatable to Power Up LINQ Distinct Queries]
http://www.eggheadcafe.com/sample-code/LINQ/0673e72e-e8e2-459e-bae4-7e0126487093/implement-iequatable-to-power-up-linq-distinct-queries.aspx
ciao Frank- Als Antwort vorgeschlagen Pawel Warmuth Samstag, 15. Januar 2011 12:21
- Als Antwort markiert Robert BreitenhoferModerator Mittwoch, 19. Januar 2011 07:29