LINQ: displaying results from empty lists

I created two objects (simplified) in C #:

class Log { entries = new List<Entry>(); DateTime Date { get; set; } IList<Entry> entries { get; set; } } class Entry { DateTime ClockIn { get; set; } DateTime ClockOut { get; set; } } 

I use the following code to initialize objects:

 Log log1 = new Log() { Date = new DateTime(2010, 1, 1), }; log1.Entries.Add(new Entry() { ClockIn = new DateTime(0001, 1, 1, 9, 0, 0), ClockOut = new DateTime(0001, 1, 1, 12, 0, 0) }); Log log2 = new Log() { Date = new DateTime(2010, 2, 1), }; 

The method used below is used to get date logs:

 var query = from l in DB.GetLogs() from e in l.Entries orderby l.Date ascending select new { Date = l.Date, ClockIn = e.ClockIn, ClockOut = e.ClockOut, }; 

The result of the above LINQ query:

 /* Date | Clock In | Clock Out 01/01/2010 | 09:00 | 12:00 */ 

My question is how best to rewrite the LINQ query above to include the results of the second object I created (Log2), since it has an empty list. In other words, I would like to display all dates, even if they do not have time values.

Expected Result:

 /* Date | Clock In | Clock Out 01/01/2010 | 09:00 | 12:00 02/01/2010 | | */ 
+6
c # linq
source share
3 answers

Try the following:

 var query = from l in DB.GetLogs() from e in l.Entries.DefaultIfEmpty() orderby l.Date ascending select new { Date = l.Date, ClockIn = e == null ? null : e.ClockIn, ClockOut = e == null ? null : e.ClockOut, }; 

Further information about it can be found in the docs for DefaultIfEmpty .

EDIT: you can just change it to execute the last part in memory:

 var dbQuery = from l in DB.GetLogs() from e in l.Entries.DefaultIfEmpty() orderby l.Date ascending select new { Date = l.Date, Entry = e }; var query = dbQuery.AsEnumerable() .Select(x => new { Date = x.Date, ClockIn = x.Entry == null ? null : x.Entry.CLockIn, ClockOut = x.Entry == null ? null : x.Entry.CLockOut }); 
+10
source share

This is built on top of the Jon solution. Using it, I get the following error:

Cannot Assign Anonymous Type Property

I updated the Jon example for the following and seems to give the desired result:

 var logs = new []{log1,log2}; var query = from l in logs.DefaultIfEmpty() from e in l.entries.DefaultIfEmpty() orderby l.Date ascending select new { Date = l.Date, ClockIn = e == null ? (DateTime?)null : e.ClockIn, ClockOut = e == null ? (DateTime?)null : e.ClockOut, }; query.Dump(); 

Andrew

PS.Dump () because of me uses LINQ Pad.

+3
source share

You should take a look at the LINQ Union operator.

http://srtsolutions.com/public/blog/251070

0
source share

All Articles