简体   繁体   English

通过 DefaultIfEmpty 等效的 LINQ Left Join SQL 无法返回结果

[英]LINQ Left Join SQL equivalent via DefaultIfEmpty fails to return results

I have had an extensive look around on SE, tried all of the suggestions, checked out MSDN how to perform Left Join equivalent in LINQ to SQL and I have constructed my LINQ query according to MSDN example.我对 SE 进行了广泛的查看,尝试了所有建议,查看了MSDN如何在 LINQ to SQL 中执行等效的左连接,并且我已经根据 MSDN 示例构建了我的 LINQ 查询。

However, the result is not what SQL would return and I am completely lost as to where am I going wrong.但是,结果不是 SQL 将返回的结果,我完全不知道我哪里出错了。

Here is some details:以下是一些细节:

I have two tables, Customers and Reports.我有两个表,客户和报告。 A customer can submit many reports or none.一个客户可以提交许多报告,也可以不提交。 In the current state I have many more reports than customers.在目前的状态下,我的报告比客户多得多。

LINQ code: 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 code: 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]

The problem is that the query returns number of elements equal to number of reports.问题是查询返回的元素数等于报告数。 However, what I want is to get a list with all customers and for those who have submitted a report I wish to display the date of the most recent report, for those who have not submitted anything, I am happy to leave it NULL or DateTime.MinValue但是,我想要的是获得所有客户的列表,对于提交报告的人,我希望显示最近报告的日期,对于没有提交任何内容的人,我很乐意将其保留为 NULL 或 DateTime .MinValue

Any help would be greatly appreciated.任何帮助将不胜感激。 I guess I am missing a group by call somewhere in my LINQ code...我想我在我的 LINQ 代码中的某个地方通过调用丢失了一个组......

Im thinking probably something like this:我想可能是这样的:

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

you are now joining on join r in reports on c.Id equals r.Id into temp this looks like: join on a customer.Id on Reports.Id, since you say there are 1 to many relation/rapport.您现在正在加入关于join r in reports on c.Id equals r.Id into temp这看起来像:在 Reports.Id 上加入 customer.Id,因为您说有 1 到多个关系/融洽关系。 I think your table will have a Reports.CustomerId.我认为你的表会有一个 Reports.CustomerId。 Is this correct?这样对吗?

So your query should something look like:所以你的查询应该是这样的:

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

the select comes out of my head, so i am probably missing something ;)选择从我的脑海中浮现,所以我可能错过了一些东西;)

Have you tried LinqPad ?你试过 LinqPad 吗? There you can type your linq-queries, and directly see your sql code and results.在那里你可以输入你的 linq-queries,并直接查看你的 sql 代码和结果。 Works like a charm!奇迹般有效!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM