【问题标题】:C# Linq Group by ObjectC# Linq 按对象分组
【发布时间】:2020-04-11 22:48:01
【问题描述】:

我在 LINQ to SQL 语句中使用 group by 时遇到问题。

我的鳕鱼是

var combinedItems = (from article in articles
                     join author in authors
                     on article.AuthorId equals author.Id into tempAuthors
                     from tempAuthor in tempAuthors.DefaultIfEmpty()
                     select new { article , author = tempAuthor});

var groups1 = (from combinedItem in combinedItems
               group combinedItem by combinedItem.article into g
               select g.Key).ToList();

var groups2 = (from combinedItem in combinedItems
               group combinedItem by combinedItem.article.Id into g
               select g.Key).ToList();

我尝试以两种不同的方式进行分组。第一种方式,我按一个对象分组,第二种方式我只是按其中一个对象中的一个字段分组。

当我运行groups1 时,我收到一条错误消息,提示需要在客户端进行评估,而当我使用groups2 时,一切正常。我能问一下有什么问题吗?如果我想按对象分组,有什么办法吗?

【问题讨论】:

  • 我认为你不能直接按对象分组,但是如果你根据初始对象的所有属性构建一个匿名对象,就可以了,比如:group combinedItem by new{combinedItem.article.Id,combinedItem.article.Name,...} into g

标签: c# .net linq linq-to-sql


【解决方案1】:

如果你想按对象分组,因为你没有在你的 Article 类中覆盖 EqualsGetHashCode() 或实现 IEqualityComparer<Article> 你只是得到默认比较,它检查引用是否是平等的。所以你需要的是这样的:

class GroupItemComparer : IEqualityComparer<Article>
{

    public bool Equals(Article x, Article y)
    {
        return x.Id == y.Id &&
            x.Name == y.Name;
    }

    public int GetHashCode(Article obj)
    {
        return obj.Id.GetHashCode() ^
            obj.Name.GetHashCode();
    }
}

然后您需要将查询更改为 lambda 表达式:

var groups1 = combinedItems.GroupBy(c => c.article , new GroupItemComparer())
                           .Select(c => c.Key).ToList();

如果您在将方法转换为 SQL 时遇到任何异常,您可以在 GroupBy 方法之前使用 AsEnumerableToList 方法,在加载数据后使用此方法,使用 Linq 执行任何进一步的操作对象,在内存中的数据上。

【讨论】:

    【解决方案2】:

    正如其他人所指出的,GroupBy 默认使用 reference 相等性,您可以通过指定一个或多个 properties 作为分组依据来绕过它。但是为什么会出现错误

    查询的重点是将您的 Linq 查询转换为 SQL。由于客户端上的对象引用相等性不能轻易转换为 SQL,因此翻译器不支持它并给您一个错误。

    当您提供一个或多个属性作为分组依据时,提供者可以将其转换为 SQL(例如GROUP BY article.Id),因此第二种方法可以正常工作.

    【讨论】:

      猜你喜欢
      • 2016-06-18
      • 1970-01-01
      • 2021-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多