【问题标题】:Simplify the LINQ query with GroupBy method使用 GroupBy 方法简化 LINQ 查询
【发布时间】:2017-09-15 06:32:38
【问题描述】:

有没有机会简化这个查询?我正在使用实体框架,当他们看到这个 DRY 违规时我的眼睛在哭。数据库有几个典型的论坛项目表:用户、帖子、主题、类别——它们都是适当的导航属性。

GetMostActiveTopicByUserID 返回特定用户最活跃的主题(最活跃 = 所有用户主题中发送的帖子最多)。

ActiveTopicDTO GetMostActiveTopicByUserID(int id)
{
    var result = _databaseContext.Users.Where(q => q.ID == id)
    .Select(user => new UserMostActiveTopicDTO()
    {
        TopicName = user.Posts.GroupBy(post => post.Topic.ID)
                    .OrderByDescending(post => post.Count())
                    .FirstOrDefault()
                    .FirstOrDefault()
                    .Topic.Name,

        TopicAlias = user.Posts.GroupBy(post => post.Topic.ID)
                    .OrderByDescending(post => post.Count())
                    .FirstOrDefault()
                    .FirstOrDefault()
                    .Topic.Alias,

        TopicCategoryDescription = user.Posts.GroupBy(post => post.Topic.ID)
                    .OrderByDescending(post => post.Count())
                    .FirstOrDefault()
                    .FirstOrDefault()
                    .Topic.Description

        //and so on...
    }).Single();

    return result;
}

【问题讨论】:

  • 你为什么打电话给FirstOrDefault().FirstOrDefault()
  • 为什么不把整个user.Posts.GroupBy(post => post.Topic.ID) .OrderByDescending(post => post.Count()) .FirstOrDefault() .FirstOrDefault() .Topic 部分放在一个方法中呢?然后做TopicName=NewMethod().NameTopicAlias=NewMethod().Alias等。
  • @maccettura:因为 GroupBy 返回 IEnumerable> - 我想从第一个最大的组中获取第一个元素。这相当于特定用户的帖子数最多的主题。有点奇怪,但我不知道如何写得更干净。
  • @Sach - 实体框架不喜欢外部方法并抛出异常。
  • 哦,我错过了EF 部分,抱歉。应该正确阅读问题。不过,标记#entityframework 可能是个好主意。

标签: c# entity-framework linq


【解决方案1】:

您的完整分组依据是基于 Topic.ID 的,那么您无需一次又一次地分组。请进行如下分组并返回结果,

CHANGE_TYPE_TO_TYPE_OF_RETURN-TYPE GetMostActiveTopicByUserID(int id)
{
    return _databaseContext.Users
        .Where(q => q.ID == id)
        .Select(user => 
        {
            user.Posts.GroupBy(post => post.Topic.ID)
                .OrderByDescending(post => post.Count())
                .FirstOrDefault()
        })
        .Single();
}

然后从返回的结果中你可以构造你的对象

【讨论】:

  • 这正是我想要的。谢谢。
猜你喜欢
  • 2018-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-16
  • 2021-10-13
  • 2020-02-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多