2015-01-29 3 views
1

집계 하위 쿼리 (개수, 합 및 최대)가 여러 개인 EF 쿼리가 있습니다. 두 가지 문제가 있습니다.Entity Framework 왼쪽 집계 쿼리에 가입

  1. 본인은이 기록이 집계 서브 쿼리의 결과가없는 경우에도 반환되도록 조인 남아있을 수있는 서브 쿼리에 조인해야합니다. 현재 모든 하위 쿼리가 레코드를 반환하는 경우에만 레코드가 반환됩니다.

  2. 반환되는 WholesaleCustomerAndAggregateOrders 개체의 결과 목록에는 주소 및 카운티도 포함해야하는 연락처 개체가 포함되어 있습니다. 쿼리에 Include(c => c.Addresses.Select(a => a.Country))을 추가했지만 연락처 개체에는 Address 개체가 포함되어 있지 않습니다.

두 가지 문제에 대한 도움을 주시면 감사하겠습니다. 아래에서 전체 검색어.

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(); 
+0

메소드에'await' 만있는 경우'return await'과 함께'async'를 사용하지 말고, 태스크 자체를 반환하십시오. 실제로 더 효율적입니다. – abatishchev

+0

감사합니다. 좋은 팁 –

답변

0

이 방법에 대해 :

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

UPDATE : DB가 당신의 문맥

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

이며, ad.ContactId이 주소에서 연락처의 FK입니다 : 투사에 다른 속성을 추가 표.

이 기능을 사용하려면 연결의 multipleactiveresultsets 속성을 True로 설정해야합니다.

+0

안녕 Milos, 고마워. 이로써 큰 성과를 올리는 통합 문제가 해결되었습니다. 그러나 연락처 여전히 채워진 Addresses 컬렉션을 반환하지 않습니다. 이 문제를 해결하기 위해 두 번째 쿼리를 수행하여 Addresses 및 Countries로 연락처를 가져온 다음 WholesaleCustomerAndAggregateOrder 개체에 연락처를 추가합니다. 누구든지이 작업을 수행하는 방법을 알고 있다면 공유하는 단일 쿼리입니다. –

+0

다른 속성을 추가하기 만하면됩니다. 업데이트를 참조하십시오. –