2010-04-06 108 views
6

我在C#創建的兩個實體(簡化):LINQ:從空列表顯示結果

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

我使用以下代碼來初始化的對象:

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

下面的方法用於獲取日期日誌:

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

上述LINQ查詢的結果是:

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

我的問題是,重寫上面的LINQ查詢以包含我創建的第二個對象(Log2)的結果的最佳方式是什麼,因爲它有一個空列表。換句話說,即使他們沒有時間值,我也想顯示所有日期。

預期的結果將是:

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

你需要發佈'executeQuery'函數......因爲這是所有重要的東西都在這裏發生的地方。 – 2010-04-06 21:21:16

+0

是否有條目和日誌之間的連接? – Nix 2010-04-06 21:23:49

回答

10

試試這個:

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

關於它的更多信息,請參見docs for DefaultIfEmpty

編輯:您可能希望只是改變它在內存中執行的最後一部分:

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

喬恩,我得到了你的例子如下:不能分配到關於與ClockIn – 2010-04-06 21:32:47

+0

,在這種情況下我已經發布了例如轉換爲(DateTime?)。我不知道你不能將null分配給匿名類型的屬性。 – 2010-04-06 21:33:07

+0

的第一次嘗試這似乎使這個例子工作,你必須轉換爲可空類型匿名類型屬性 – 2010-04-06 21:40:04

3

這是建立在喬恩的解決方案之上。使用它,我得到以下錯誤:

Cannot assign to anonymous type property

我已經更新Jon的例子下面,它似乎得到期望的結果:

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

安德魯

附: .Dump()是由於我使用了LINQ Pad。

+0

謝謝你的回答,它非常完美! – 2010-04-07 03:34:54