实体框架左连接聚合查询

时间:2015-01-29 12:34:33

标签: c# entity-framework entity-framework-6

我有一个EF查询,其中包含许多聚合子查询(Count,Sum和Max)。有两个问题。

  1. 我需要将子查询的连接保留为连接,以便即使聚合子查询中没有结果也会返回记录。目前,只有在所有子查询都返回记录时才会返回记录。

  2. 返回的WholesaleCustomerAndAggregateOrders对象的结果列表包含一个需要还包含地址和县的Contact对象。我在查询中添加了Include(c => c.Addresses.Select(a => a.Country)),但Contact对象不包含任何Address对象。

  3. 对任何一个问题的任何帮助将不胜感激。完整查询如下。

    var month1Date = DateTime.Today.AddMonths(-1);
    var month3Date = DateTime.Today.AddMonths(-3);
    var month6Date = DateTime.Today.AddMonths(-6);
    var month12Date = DateTime.Today.AddMonths(-12);
    
    var db = GetNewContext();
    var qry = from c in db.Contacts
                          .Include(c => c.Addresses.Select(a => a.Country))
              join orderCount in
                  (
                      from o in db.WholesaleOrders
                      group o by o.ContactId into g
                      select new
                      {
                          ContactId = g.Key,
                          TotalOrders = g.Count()
                      }
                  ) on c.Id equals orderCount.ContactId
              join month1Value in
                  (
                      from o in db.WholesaleOrders
                      where o.OrderDate >= month1Date
                      group o by o.ContactId into g
                      select new
                      {
                          ContactId = g.Key,
                          TotalValue = g.Sum(r => r.LineItems.Sum(l => l.QuantityOrdered * l.Price))
                      }
                  ) on c.Id equals month1Value.ContactId
              join month3Value in
                  (
                      from o in db.WholesaleOrders
                      where o.OrderDate >= month3Date
                      group o by o.ContactId into g
                      select new
                      {
                          ContactId = g.Key,
                          TotalValue = g.Sum(r => r.LineItems.Sum(l => l.QuantityOrdered * l.Price))
                      }
                  ) on c.Id equals month3Value.ContactId
              join month6Value in
                  (
                      from o in db.WholesaleOrders
                      where o.OrderDate >= month6Date
                      group o by o.ContactId into g
                      select new
                      {
                          ContactId = g.Key,
                          TotalValue = g.Sum(r => r.LineItems.Sum(l => l.QuantityOrdered * l.Price))
                      }
                  ) on c.Id equals month6Value.ContactId 
              join month12Value in
                  (
                      from o in db.WholesaleOrders
                      where o.OrderDate >= month12Date
                      group o by o.ContactId into g
                      select new
                      {
                          ContactId = g.Key,
                          TotalValue = g.Sum(r => r.LineItems.Sum(l => l.QuantityOrdered * l.Price))
                      }
                  ) on c.Id equals month12Value.ContactId
              join month12Quantity in
                  (
                      from o in db.WholesaleOrders
                      where o.OrderDate >= month12Date
                      group o by o.ContactId into g
                      select new
                      {
                          ContactId = g.Key,
                          OrderCount = g.Count()
                      }
                  ) on c.Id equals month12Quantity.ContactId
              join lastOrderDate in
                  (
                      from o in db.WholesaleOrders
                      group o by o.ContactId into g
                      select new
                      {
                          ContactId = g.Key,
                          LastOrderDate = g.Max(r => r.OrderDate)
                      }
                  ) on c.Id equals lastOrderDate.ContactId
              select new WholesaleCustomerAndAggregateOrders
              {
                  Contact = c,
                  TotalOrders = orderCount.TotalOrders,
                  Month1Value = month1Value.TotalValue,
                  Month3Value = month3Value.TotalValue,
                  Month6Value = month6Value.TotalValue,
                  Month12Value = month12Value.TotalValue,
                  Month12OrderCount = month12Quantity.OrderCount,
                  LastOrderDate = lastOrderDate.LastOrderDate
              };
    
    return await qry.ToListAsync();
    

1 个答案:

答案 0 :(得分:1)

这个怎么样:

db.WholesaleOrders
    .GroupBy(o => o.ContactId)
    .Select(a => new { 
        a.Key, 
        TotalOrders = a.Count(),
        LastOrderDate = a.Max(r => r.OrderDate),
        Month1Value = a.Where(b => b.OrderDate >= month1Date).Sum(r => r.LineItems.Sum(l => l.QuantityOrdered * l.Price),
        Month3Value = a.Where(b => b.OrderDate >= month3Date).Sum(r => r.LineItems.Sum(l => l.QuantityOrdered * l.Price),
        Month6Value = a.Where(b => b.OrderDate >= month6Date).Sum(r => r.LineItems.Sum(l => l.QuantityOrdered * l.Price),
        Month12Value = a.Where(b => b.OrderDate >= month12Date).Sum(r => r.LineItems.Sum(l => l.QuantityOrdered * l.Price)
        }).ToListAsync();

更新:向投影添加另一个属性:

Addresses = db.Addresses.Where(ad => ad.ContactId == a.Key);

其中db是您的上下文,ad.ContactId是地址表中联系人的FK。

为此,连接的multipleactiveresultsets属性必须设置为True。