【问题标题】:How to group by property of child entity and get sum of child entity in linq?如何按子实体的属性分组并在linq中获取子实体的总和?
【发布时间】:2021-06-26 18:55:06
【问题描述】:

我需要按子实体对数据进行分组并获取子实体的总和。所以,我尝试了这个 linq:

context.Parent.Include(p => p.Child).GroupBy(p => p.Child.Type).Select(g => g.Sum(p => p.Child.Amount));

上面的 linq 会导致错误。但是,如果我要获得父实体的总和,它将起作用。

context.Parent.Include(p => p.Child).GroupBy(p => p.Child.Type).Select(g => g.Sum(p => p.Amount));

为什么我不能得到子实体的总和?

【问题讨论】:

  • 错误是什么?什么版本的 EF Core:2.0 / 2.1 / 3.x / 5.x?

标签: c# .net linq asp.net-core entity-framework-core


【解决方案1】:

这是限制。在 GroupBy 之后,您不能使用导航属性。同样在 GroupBy 之后,所有的 Includes 都被完全忽略了,所以省略它们。

你的查询可以这样写:

var query = 
    from p in context.Parent
    group p.Child by p.Child.Type into g
    select new 
    {
        Type = g.Key,
        Sum = g.Sum(c => c.Amount)
    };

Lambda 语法变体:


var query = context.Parent
    .GroupBy(p => p.Child.Type, p => p.Child)
    .Select(g => new 
    {
       Type = g.Key, 
       Sum = g.Sum(c => c.Amount)
    });

【讨论】:

  • 我无法在 lambda 中实现上述 linq。能提供lambda函数实现吗?
  • 安装 ReSharper 并单击即可完成。这将是丑陋且无法维护的。学习 LINQ 查询。
  • @ranjeep,添加了 Lambda 语法变体。
  • 如果我需要按父实体的属性分组,得到子实体的属性总和怎么办?正如您提到的,group by 导航属性无法使用后,如何实现?
  • 在 GroupBy 之后,我的意思是在投影中。摸索键可以是导航属性。
【解决方案2】:

显然,在您的模型中,您有一个Parents 序列。每个Parent 都有一个属性Child。每个Child 都有两个属性:AmountType

您忘记告诉我们您的规范,并给了我们一些不符合您要求的代码。所以我们很难知道你想要什么。

我认为您希望将Parents 的组与Parent.Child.Type 的值相同。您希望从组中的每个家长中获取 Parent.Child.Amount 的值并对这些值求和。

你是对的,为此你应该使用 Enumerable.GroupBy 的重载之一。我的建议是使用具有参数 resultSelector 的重载:

// make groups of Parents with same value of Parents.Child.Type:
var result = dbContext.Parents.GroupBy(parent => parent.Child.Type,

// parameter resultSelector: for every Type, and all Parents that have this Child.Type
// make one new:
(type, parentsWithThisChildType) => new
{
    // do you want to know the type?
    ChildType = type,

    // from all parents in this group, select the Parent.Child.Amount and Sum them:
    TotalChildAmounts = parentsWithThisChildType
        .Select(parent => parent.Child.Amount)
        .Sum(),
})

换句话说:从您的父母序列中,创建具有相同 Parent.Child.Type 值的父母组。从每个组中制作一个对象,如下所示:

  • 可取,取本组所有Parent.Child.Type的通用Type
  • 从组中的每个 Parent 中选择 Parent.Child.Amount 的值。
  • 对这个 Amound 的所有值求和,并将结果放入 TotalChildAmounts

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多