问题
I'm trying to populate a Drop down list with pharmaceutical companies, like Bayer, Medley etc. And, I'm getting theses names from DB and theses names are repeated in DB, but with different id's.
I'm trying to use Linq Distinct(), but I don't want to use the equality comparer. Is there another way?
My drop down list must be filled with the id and the name of the company.
I'm trying something like:
var x = _partnerService
.SelectPartners()
.Select(c => new {codPartner = c.codPartner, name = c.name})
.Distinct();
This is showing repeated companies in ddl.
thanks!
回答1:
The following expression will select only distinct companies and return the first occurence with its id.
partnerService.SelectPartners().GroupBy(p => p.Name).Select(g => g.First());
回答2:
var distinctCompanies = Companies
.GroupBy(c => c.CompanyName)
.Select(g => g.First());
回答3:
Distinct works on the entire select. If you include c.codPartner in the select, and there are two different values of c.codPartner for the same c.name, then you are going to see two rows with the same c.name.
回答4:
I don't think you can do this with an anonymous class, but if you created a data object like
class Foo
{
private int _ID;
public int ID
{
get { return _ID; }
set { _ID = value; }
}
private string _Name;
public string Name
{
get { return _Name; }
set { _Name = value; }
}
}
you could create a comparer object like
class FooComparer : IEqualityComparer<Foo>
{
public bool Equals(Foo x, Foo y)
{
return x.Name == y.Name;
}
public int GetHashCode(Foo obj)
{
return obj.GetHashCode();
}
}
回答5:
If you do not specify a IEqualityComparer parameter, then it will just use Object.ReferenceEquals, which looks at the objects GetHashKey value. For anonymous types, they are unique.
Now solving this is a bit tricky, since you cannot write an IEqualityComparer for an anonymous type. So you muct create a real type for the problem:
class Partner
{
public int codPartner {get; set;}
public string name {get; set;}
public override int GetHashCode() { return name .GetHashCode();}
}
var x = _partnerService.SelectPartners()
.Select(c => new Partner {codPartner = c.codPartner, name = c.name})
.Distinct();
回答6:
Distinc will use GetHashCode if you don´t tell it (via an IEqualityComparer) to use another method. You could use a generic equalitycomparer, like this:
public class GenericEqualityComparer<T> : IEqualityComparer<T>
{
private Func<T, T, Boolean> comparer;
public GenericEqualityComparer(Func<T, T, Boolean> comparer)
{
this.comparer = comparer;
}
#region IEqualityComparer<T> Implementation
public bool Equals(T x, T y)
{
return comparer(x, y);
}
public int GetHashCode(T obj)
{
return obj.GetHashCode();
}
#endregion
}
and then use like this (kindof)
public static IEqualityComparer<YourType> MyComparer
{
get
{
return new GenericEqualityComparer<YourType>((x, y) =>
{
return x.name.Equals(y.name);
});
}
}
回答7:
just pass in your own comparer to the Distinct method using one of the other overloads.
(extension) IQueryable<T> IQueryable<T>.Distinct( IEqualityComparer<T> comparer )
来源:https://stackoverflow.com/questions/912188/linq-distinct-by-name-for-populate-a-dropdown-list-with-name-and-value