具有多个GroupBy要求的多个连接的LINQ扩展方法

时间:2017-10-27 00:49:49

标签: c# entity-framework linq

作为学习EF的练习,我有以下4个表格。 Person 1toM Orders M2M Products via OrderProducts Enum性别public class Person { public int Id { get; set; } public string Name { get; set; } public Gender Gender { get; set; } public IList<Order> Orders { get; set; } } public class Order { public int Id { get; set; } public int PersonId { get; set; } public Person Person { get; set; } public IList<OrderProduct> OrderProducts { get; set; } } public class OrderProduct { public int Id { get; set; } public int Qty { get; set; } public Order Order { get; set; } public int OrderId { get; set; } public Product Product { get; set; } public int ProductId { get; set; } } public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public IList<OrderProduct> OrderProducts { get; set; } } ):

[=Sum(OrderProducts.Qty * Product.Price)]

我尝试使用LINQ扩展方法生成以下内容:

  

产品列表和总费用Female Ball $655.60 Bat $1,925.40 Glasses $518.31 Etc... Male Ball $1,892.30 Bat $3,947.07 Glasses $1,315.71 Etc... ,按产品名称分组,然后按性别分组。

结果看起来像这样:

ProductName

我承诺使用 LINQ 扩展方法,并希望我也可以在这里开发一些最佳实践。我无法确定如何按Qty * 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)

我尝试将Git添加到最后但得到错误&#34; 用于调用&#39; GroupBy&#39;的密钥选择器类型方法在底层商店提供商中无法比较。&#34;。

2 个答案:

答案 0 :(得分:2)

我想你差不多...... 试试这个:

       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
                                                                    }))
                                      });

简而言之,您只需要更多投影。在我建议的解决方案中,首先按性别分组。下一步是预测性别和产品列表&#39;直接(是的,难以绕过的是OrderProducts)。在Products我们按产品名称对其进行分组,然后取总量(Qty)并设置Price - 假设同一产品的价格不变。下一步是设置TotalPriceQty * Price

聚苯乙烯。我完全清楚这个查询有很多不足之处。也许LINQ专家可以为此提供更好的帮助。

这将导致类如下:

  {
    Gender Gender
    IEnumerable<{ ProductName, Qty, Price, TotalPrice }> Products
  }

是的,匿名类型......

尽管如此,由于问题包含有问题的模型和OP提供的尝试,我感到困惑。

答案 1 :(得分:1)

最后,这是我的解决方案,完全按照要求生成结果。

{{1}}

我要感谢@Bagus Tesa