简体   繁体   中英

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.

However, the result is not what SQL would return and I am completely lost as to where am I going wrong.

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:

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:

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

Any help would be greatly appreciated. I guess I am missing a group by call somewhere in my LINQ code...

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. I think your table will have a 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 ? There you can type your linq-queries, and directly see your sql code and results. Works like a charm!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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