2017-10-17 20 views
1

我已經對SE進行了廣泛的瞭解,嘗試了所有的建議,檢出了MSDN如何在LINQ to SQL中執行Left Join等效項,並且構建了我的LINQ查詢根據MSDN的例子。LINQ Left通過DefaultIfEmpty加入SQL等效項無法返回結果

但是,結果不是SQL會返回什麼,我完全失去了我要去哪裏錯誤。

這裏有一些細節:

我有兩個表,Customers和Reports。客戶可以提交很多報告或不提交。在目前的狀態下,我的報告比客戶多得多。

LINQ代碼:

var query = {from c in customers 
      join r in reports on c.Id equals r.Id into temp 
      from items in temp.DefaultIfEmpty() 
      select new { 
       c.Id, 
       LastReportDate = items?.DateCreated ?? DateTime.MinValue 
      }).ToList(); 

SQL代碼:

SELECT [Customers].[Id], R.LastReport AS LastReportDate FROM [Customers] 
LEFT JOIN ( 
      SELECT Reports.Id, MAX([Reports].[Created]) AS LastReport 
      FROM Reports GROUP BY Reports.Id 
     ) AS r ON [Customers].[Id] = r.[Id] 

的問題是,該查詢返回等於報告數元素的數目。但是,我想要的是獲得所有客戶和提交報告的人的列表,我希望顯示最新報告的日期,對於那些沒有提交任何內容的人,我很樂意讓它留NULL或DateTime .MinValue

任何幫助將不勝感激。我想我通過電話某處在我的LINQ代碼所缺少一組...

+1

你確定'on c.Id等於r.Id'是否正確?是不是像'在c.Id等於r.CustomerId'上?目前,您正在將客戶ID與報告ID相關聯。 –

+0

Linq代碼生成的SQL?或者你是否試圖在linq中編寫這條sql語句? – Magnus

+0

@Magnus我正在嘗試在LINQ中編寫SQL語句 – awdBoy

回答

1

即時通訊思想大概是這樣的:

var query = 
     from c in customers 
     join r in reports on c.Id equals r.Id into g 
     select new 
     { 
      c.Id, 
      LastReportDate = g.Max(x => (DateTime?)x.Created) 
     }; 
+0

@GiladGreen如果'Created'是可以爲空的,它將返回'null',這在問題中是可以接受的,也是SQL所做的。如果不是,我們可以將它轉換爲可以爲空的DateTime。 – Magnus

0

現在你已經加入了關於join r in reports on c.Id equals r.Id into temp 這個樣子:加入一個客戶.Id on Reports.Id,因爲你說有1對多關係/融洽關係。我認爲你的表格將有一個Reports.CustomerId。它是否正確?

所以,你的查詢應該什麼樣子:

var results = customer.Where(c => c.Reports.Any()) 
         .SelectMany(c => {c, c.Reports.Max(r => r.Created)}) 
         .ToList(); 

選擇出來我的頭,所以我可能失去了一些東西;)

你試過LinqPad?在那裏你可以輸入你的linq-queries,並直接看到你的sql代碼和結果。奇蹟般有效!