C# 具有多个GroupBy需求的多连接LINQ扩展方法
作为学习C# 具有多个GroupBy需求的多连接LINQ扩展方法,c#,entity-framework,linq,C#,Entity Framework,Linq,作为学习EF的练习,我有以下4个表Person 1toM,通过OrderProducts订购M2M,产品(性别是一个Enum): 我致力于LINQ扩展方法,希望我也能在这里开发一些最佳实践。我现在无法确定如何按ProductName进行分组,并将quaty*Price汇总为按产品列出的总数: var prodsalesbygender = context.Orders .GroupBy(o => new { Gender = o.Person.Ge
EF
的练习,我有以下4个表Person 1toM
,通过OrderProducts订购M2M,产品(性别是一个Enum
):
我致力于LINQ扩展方法,希望我也能在这里开发一些最佳实践。我现在无法确定如何按ProductName
进行分组,并将quaty*Price
汇总为按产品列出的总数:
var prodsalesbygender = context.Orders
.GroupBy(o => new
{
Gender = o.Person.Gender
})
.Select(g => new
{
ProductName = g.Select(o => o.OrderProducts.Select(op => op.Product.Name)),
Qty = g.Select(o => o.OrderProducts.Select(op => op.Qty)),
Price = g.Select(o => o.OrderProducts.Select(op => op.Product.Price))
}
);
我已尝试将.GroupBy(g=>g.ProductName)
添加到末尾,但出现错误“用于调用'GroupBy'方法的键选择器类型在基础存储提供程序中不可比较。” 我想你就快到了。。
试试这个:
var prodsalesbygender = context.Orders
.GroupBy(o => new
{
Gender = o.Person.Gender
})
.Select(g => new
{
Gender = g.Key,
Products = g.Select(o => o.OrderProducts
.GroupBy(op => op.Product)
.Select(op => new
{
ProductName = op.Key.Name,
Qty = op.Sum(op2 => op2.Qty),
Price = op.Select(x => x.Product.Price)
.First(),
})
.Select(x => new
{
ProducName = x.ProductName,
Qty = x.Qty,
Price = x.Price,
TotalPrice = x.Qty * x.Price
}))
});
简而言之,你只需要更多的投影。在我建议的解决方案中,首先按性别分组。下一步是直接预测性别和“产品列表”(是的,难以绕过的部分是OrderProducts
)。在产品中
我们根据产品名称对其进行分组,然后获取总数量(数量
),并设置价格
——假设相同产品的价格是恒定的。下一步是设置TotalPrice
,Qty*Price
东西
另外,我完全知道这个问题有很多不足之处。也许LINQ专家可以在这方面提供更好的帮助
它将生成一个类似以下内容的类:
{
Gender Gender
IEnumerable<{ ProductName, Qty, Price, TotalPrice }> Products
}
{
性别
可数产品
}
是的,匿名类型就到此为止
尽管如此,我还是被否决票难住了,因为该问题包含有问题的模型和OP提供的尝试。最后,这是我的解决方案,产生的结果完全符合要求
var prodsalesbygender = context.OrderProducts
.GroupBy(op => new
{
Gender = op.Order.Person.Gender
})
.Select(g => new
{
Gender = g.Key.Gender,
Products = g.GroupBy(op => op.Product)
.Select(a => new
{
ProductName = a.Key.Name,
Total = a.Sum(op => op.Qty * op.Product.Price)
})
.OrderBy(a => a.ProductName)
});
foreach (var x in prodsalesbygender)
{
Console.WriteLine(x.Gender);
foreach (var a in x.Products)
Console.WriteLine($"\t{a.ProductName} - {a.Total}");
}
感谢@Bagus Tesa大家好,欢迎来到Stack Overflow!这是一个有趣的问题,但我认为你应该把它编辑得更短。您是否可以大幅减少代码块,以获得最小数量的代码来重现和表示您的问题?这样,更多的人会阅读问题,你会更快地得到答案。还有,你试过什么,但没有用?简单地提及那些没有起作用的东西也会改善这个问题。谢谢,祝你好运!谢谢Max-我已经删除了一些不相关的属性并接受了你的建议。只是在这里学习,不用担心!谢谢你澄清这个问题。我不是LINQ专家,但你的问题越短、可读性越强,LINQ专家就越有可能阅读并回答它。祝你好运非常感谢你的帮助。我运行了您的查询,当它计算总数时,它在订单级别按记录进行计算,但不聚合到产品级别。越来越近。。。我很欣赏你对否决票的评论——作为一个努力学习并最终做出贡献的相对新人,他们有点令人沮丧。我会及时了解的。嗨@deldridg,我理解你的担忧,但是,订单产品
只有数量
,没有价格。。因此,我们需要从产品
本身获取价格。嗨@Bagus Tesa-这就是我试图解决的问题。正如你所说的,我试图返回你描述的类。我们的新查询为每个订单返回一个IEnumerable(总共100个),而不是一个产品列表(总共10个),如果这有意义的话!啊,我明白你的问题了,我们不应该从订单上解决这个问题。。因为我们是根据性别和总销售额汇总产品
,对吗?编辑,嗯,我认为,从产品是不可行的。嗯-听起来正确。我在没有性别条款的情况下一直在讨论这个问题,而且似乎有点接近了。不确定我是否可以在这里发布“部分解决方案”。。。
{
Gender Gender
IEnumerable<{ ProductName, Qty, Price, TotalPrice }> Products
}
var prodsalesbygender = context.OrderProducts
.GroupBy(op => new
{
Gender = op.Order.Person.Gender
})
.Select(g => new
{
Gender = g.Key.Gender,
Products = g.GroupBy(op => op.Product)
.Select(a => new
{
ProductName = a.Key.Name,
Total = a.Sum(op => op.Qty * op.Product.Price)
})
.OrderBy(a => a.ProductName)
});
foreach (var x in prodsalesbygender)
{
Console.WriteLine(x.Gender);
foreach (var a in x.Products)
Console.WriteLine($"\t{a.ProductName} - {a.Total}");
}