【问题标题】:c# distinct doesn't work. what i'm doing wrong?c# distinct 不起作用。我做错了什么?
【发布时间】:2019-07-14 15:10:58
【问题描述】:

我正在开发一个 asp.net 核心应用程序。
我有一个获取属性值的代码。

var properties = _context.Properties.Select(p => new {
    p.Name,
    Values = p.Values.Distinct()
}).Distinct();

但是 Distinct() 不起作用。我做错了什么?

【问题讨论】:

  • “不起作用”是什么意思?你是指哪个Distinct
  • 我得到了相同的元素。我的意思是第二个 Distinct。
  • 你得到了什么元素?显示一些输入、您的预期输出和实际输出,并指出问题所在。
  • 我得到一个包含值的属性。还有一些属性重复。
  • 我要求您展示您放入和取出的那些属性的实际,而不仅仅是描述它们的 ,因为这是您解释代码有什么问题的最清晰的方式。

标签: c# linq entity-framework-core


【解决方案1】:

问题是第二个Distinct 不知道如何比较项目。可能您的意思是按名称区分,而不是按所有属性区分。

不要创建匿名类型,而是创建一个命名类型(即Property)。然后为这个类型声明一个IEqualityComparer<T>

class PropertyNameComparer : IEqualityComparer<Property>
{
    public bool Equals(Property x, Property y) => x.Name.Equals(y.Name);
    public int GetHashCode(Property p) => p.Name.GetHashCode();
}

(为简单起见,我这里不处理空值。)

var properties = _context.Properties.Select(p => new Property {
    Name = p.Name,
    Values = p.Values.Distinct()
})
.AsEnumerable()
.Distinct(new PropertyNameComparer());

注意.AsEnumerable() 将查询与第二个Distinct 分开以使其成为LINQ-to-Objects,因为EF 无法将IEqualityComparer&lt;T&gt; 转换为SQL。

但真正的问题是,为什么您首先会得到重复的属性?如果这样做,您希望重复项的值发生什么变化?它们会包含相同的值还是不同的值?我的实现只采用第一个属性及其值并忽略重复项的值。相反,您可能希望按名称分组并合并这些值。但你的问题并不清楚。

【讨论】:

  • 感谢您的回答。但是我得到一个错误:'IEnumerable >值>>“不包含”不同“的定义,最合适的重载扩展方法是“ Queryable.Distinct (IQueryable , IEqualityComparer )”需要类型为“IQueryable ”的收件人
  • 因为你还在使用new { ... },导致了匿名类型。请改用new Property { ... } 来获取已知类型。您也可以使用其他类型,只要它与IEqualityComparer&lt;T&gt; 中的T 匹配即可。
  • C# 按属性比较匿名对象,而不是按引用,但是 Values 属性将按引用进行比较,因为它的类型。如果 Values 属性被忽略,Distinct 将只为每个 Name 的值产生一个结果,因为 strings 按值进行比较,即使它们仍然是不同的实例。
猜你喜欢
  • 1970-01-01
  • 2012-06-13
  • 1970-01-01
  • 1970-01-01
  • 2013-05-16
  • 2017-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多