2017-10-17 19 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代码和结果。奇迹般有效!