C# 使用名称和值填充下拉列表的Linq Distinct()
我正在尝试用制药公司填充一个下拉列表,如拜耳、Medley等。我从DB获得这些名称,这些名称在DB中重复,但id不同 我试图使用Linq Distinct,但我不想使用相等比较器。还有别的办法吗 我的下拉列表必须填写id和公司名称 我正在尝试类似的东西:C# 使用名称和值填充下拉列表的Linq Distinct(),c#,linq-to-sql,distinct,C#,Linq To Sql,Distinct,我正在尝试用制药公司填充一个下拉列表,如拜耳、Medley等。我从DB获得这些名称,这些名称在DB中重复,但id不同 我试图使用Linq Distinct,但我不想使用相等比较器。还有别的办法吗 我的下拉列表必须填写id和公司名称 我正在尝试类似的东西: var x = _partnerService .SelectPartners() .Select(c => new {codPartner = c.codPartner, name = c.n
var x = _partnerService
.SelectPartners()
.Select(c => new {codPartner = c.codPartner, name = c.name})
.Distinct();
这显示了ddl中的重复公司
谢谢 Distinct在整个select上工作。如果在选择中包括c.codPartner,并且同一个c.name有两个不同的c.codPartner值,那么您将看到两行具有相同的c.name。只需使用其他重载之一将自己的比较器传递到Distinct方法
(extension) IQueryable<T> IQueryable<T>.Distinct( IEqualityComparer<T> comparer )
如果不指定IEqualityComparer参数,那么它将只使用Object.ReferenceEquals,它查看对象的GetHashKey值。对于匿名类型,它们是唯一的 现在解决这个问题有点棘手,因为您无法为匿名类型编写IEqualityComparer。因此,您必须为问题创建一个真正的类型:
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();
我不认为你可以用匿名类来实现这一点,但是如果你创建了一个数据对象,比如
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; }
}
}
class FooComparer : IEqualityComparer<Foo>
{
public bool Equals(Foo x, Foo y)
{
return x.Name == y.Name;
}
public int GetHashCode(Foo obj)
{
return obj.GetHashCode();
}
}
您可以创建比较器对象,如
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; }
}
}
class FooComparer : IEqualityComparer<Foo>
{
public bool Equals(Foo x, Foo y)
{
return x.Name == y.Name;
}
public int GetHashCode(Foo obj)
{
return obj.GetHashCode();
}
}
如果您没有通过IEqualityComparer告诉Distinc使用另一种方法,Distinc将使用GetHashCode。 您可以使用通用的equalitycomparer,如下所示:
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
}
然后像这样使用
public static IEqualityComparer<YourType> MyComparer
{
get
{
return new GenericEqualityComparer<YourType>((x, y) =>
{
return x.name.Equals(y.name);
});
}
}
下面的表达式将只选择不同的公司,并返回第一个id为的公司
partnerService.SelectPartners().GroupBy(p => p.Name).Select(g => g.First());
如果一个公司使用不同的id多次出现,而您希望它们只出现一次,那么应该显示什么id?第一个?没关系?这不会改变任何事。。。如果有几家公司名称相同但id不同,您会如何选择要使用的id?我同意-选择id将是一个问题。如果您想为每个应用程序指定一个特定的ID,那么使用distinct和EqualityComparer可能不是一个好办法。另外,请记住这里的否决票,原来的问题没有提到为不同结果中的每个项目选择特定的ID…ReferenceEquals不比较哈希代码,它比较引用。。。只有当两个引用指向同一个实例时,它才会返回true嗨Daniel!这正是我所需要的!谢谢-当我这样做时:dgvRecords.DataSource=来自dbContext.records中的g选择g.GroupByg=>g.ID.Selectg=>g.FirstOrDefault;I get:Message=不支持指定的方法。Source=MySql.Data。Entity@AndreMiranda您可以使用groupby并在主linq select的末尾选择,这非常有用@Daniel Brückner,TNX对于VB.net人员,使用.GroupByFunctionp p p.Name.SelectFunctiong g.首先还要确保导入System.Linq,否则您将无法在IGrouping类的select调用中获得第一个函数只是因为我一开始不理解这一点,它所做的是按名称对列表进行分组-[john,john,george,george,george]-然后只选择每个内部组中的第一个,并将其放入列表中。对不起,请问“g”来自哪里?@StarCub companys是一个IEnumerable。GroupBy接受并返回IEnumerable。选择中的每个项目都是一个iGroup。我使用了一个不同的名称,以使类型上的差异更加明显。