2015-08-27 1 views
3

Я пытаюсь преобразовать свой T-SQL в LINQ. Это дает мне настоящую головную боль. Может кто-нибудь указать на то, что я делаю неправильно здесь:Преобразование T-SQL в LINQ с платформой Entity

T-SQL 
select 
    h.DateStamp 
, h.Machine 
, h.SalesInvoice 
, h.Status 
, sum(i.Quantity)           totalquantity 
, sum(IIF(h.[Status]='SALES', i.Quantity, 0))    as SalesQty 
, sum(IIF(h.[Status]='RETURNS', i.Quantity, 0))    as ReturnQty 
, sum(IIF(h.[Status]='SALES', i.Quantity*i.Soldsrp , 0)) as SalesGross 
, sum(IIF(h.[Status]='RETURNS', i.Quantity*i.Soldsrp, 0)) as ReturnGross 
, sum(IIF(h.[Status]='SALES', i.DiscountAmount , 0))  as SalesDiscount 
, sum(IIF(h.[Status]='RETURNS', i.DiscountAmount, 0))  as ReturnDiscount 
, sum(IIF(h.[Status]='SALES', i.TotalAmount , 0))   as SalesACD 
, sum(IIF(h.[Status]='RETURNS', i.TotalAmount , 0))   as ReturnACD 

from CSHR_SalesItems i 
left join CSHR_SalesHeader h on h.SalesOrderNum = i.SalesOrderNum 
where H.DateStamp between '2015-08-20 00:00:00.000' and '2015-08-27 23:59:00.000' 

group by h.DateStamp, h.Machine, h.SalesInvoice, h.[Status] 

Вот моя попытка превратить его в LINQ с рамкой сущности. GroundCommander является субъектом

using (var GC = new GroundCommanderEntities()) 
{ 
    foreach (var item in GC.CSHR_SalesItems) 
    { 
     var Summary = 
      from i in GC.CSHR_SalesItems 
      join h in GC.CSHR_SalesHeader on item.SalesOrderNum equals h.SalesOrderNum into IH 
      from h in IH 
      where (h.DateStamp >= dateTimePickerStart.Value && h.DateStamp <= dateTimePickerLast.Value)     
      select new { 
       h.DateStamp, 
       h.Machine, 
       h.SalesInvoice, 
       h.Status, 
       i.Quantity //need to get the sum 
      }; 
    } 
+0

Вам нужно 'от h в IH.DefaultIfEmpty()' сделать его левым соединением. – juharr

+0

Спасибо, я этого не заметил. –

+0

Хотя я не думаю, что вам нужно левое соединение вообще, поскольку где будет false, когда левая сторона равна нулю. – juharr

ответ

1

Я считаю, что это то, что вы хотите.

var Summary = 
    from i in GC.CSHR_SalesItems 
    join h in GC.CSHR_SalesHeader on item.SalesOrderNum equals h.SalesOrderNum 
    where (h.DateStamp >= dateTimePickerStart.Value 
      && h.DateStamp <= dateTimePickerLast.Value)  
    group new { item = i, header = h} 
     by new {h.DateStamp, h.Machine, h.SalesInvoice, h.Status} into grp 
    select new { 
     grp.Key.DateStamp, 
     grp.Key.Machine, 
     grp.Key.SalesInvoice, 
     grp.Key.Status, 
     TotalQuanity = grp.Sum(x => x.item.Quantity), 
     SalesQty = grp.Where(x => x.header.Status == "SALES").Sum(x => x.item.Quantity), 
     ... 
    }; 

Во-первых, я избавилась от соединения слева, потому что в любое время правая сторона null, что где бы ложь в любом случае. Во-вторых, я добавил группу, по которой будет создана соответствующая группировка. Затем в выборе вы можете сделать, вы суммируете сумму, и я привел вам пример того, как фильтровать на основе статуса для ваших других итогов.

+0

Мне любопытно, какой SQL будет создан для этого, и если бы он был так же эффективен, как и ручное кодирование. – Dai

+0

Вы можете использовать SQL Server Profiler для просмотра того, что создано. Обычно EF SQL намного труднее читать. Вы можете запускать оба в SSMS, чтобы увидеть, отличаются ли планы выполнения. – juharr

+0

Я сейчас пытаюсь. Чтение кода до сих пор выглядит правильно. Спасибо, –

Смежные вопросы