2010-03-15 269 views
0

我可以發誓,這是工作的一天:LINQ到實體 - 空引用

var resultSet = 
    (from o in _entities.Table1 
    where o.Table2.Table3.SomeColumn == SomeProperty 
    select o 
    ).First(); 
SelectedItem = resultSet.Table2.SomeOtherColumn; 

我收到的最後一行空引用異常:resultSet.Table2爲空。
不僅我確定所有的外鍵和沒有正確的值,但我不知道如何Table2 可能爲空,因爲o.Table2.Table3.SomeColumn == SomeProperty

resultSet具有所有正確的值,除了Table2爲空。

[編輯]這工作:

SelectedItem = _entities.Table2.First(
    o => o.Table2.SomeColumn == SomeProperty).SomeOtherColumn; 

而且,上面 resultSet擁有所有正確的價值觀,所以它不與數據庫中的數據有問題; LINQ到實體只是做錯了事情。

+0

我想你應該添加獲取Table2的代碼,因爲問題在於提取它,而不是整個查詢。 –

+0

@Andrew:但resultSet.Table2應該指向resultSet的(唯一)引用的Table2行,不應該嗎?我之前完成了這個工作,沒有任何問題,我相當肯定這就是它的存在...... –

+0

如果Table1爲空,「where o.Table2.Table3.SomeColumn ...」將不會執行,所以理論上Table2可能是空的。 – Kamarey

回答

5

LINQ到實體僅僅是做錯了什麼。

不,它按設計工作。強制它時,L2E在表格中只有JOIN。這提高了性能。只要你在L2E中,你可以引用任何關係。這就是爲什麼這個工程:

SelectedItem = _entities.Table2.First(
    o => o.Table2.SomeColumn == SomeProperty).SomeOtherColumn; 

你拉姆達這裏表達將LINQ被解釋爲實體,並轉換爲SQL。在另一方面,這樣的:

var resultSet = 
    (from o in _entities.Table1 
    where o.Table2.Table3.SomeColumn == SomeProperty 
    select o 
    ).First(); 
SelectedItem = resultSet.Table2.SomeOtherColumn; 

...給Table1類型的結果。你現在在物體空間。由於您的查詢不會強制加載Table2,因此L2E不會爲其生成SQL列。當您不需要Table2時,這會產生更高效的SQL。當你這樣做,你必須這樣說:

var resultSet = 
    (from o in _entities.Table1.Include("Table2") 
    where o.Table2.Table3.SomeColumn == SomeProperty 
    select o 
    ).First(); 

SelectedItem = resultSet.Table2.SomeOtherColumn; 

這將工作。 但是,您的First(lambda)以上方法是更好的解決方案。 (比較SQL。)

+0

我剛剛意識到我的第二個查詢給* *錯誤的結果,因爲表2 - >表3是一 - >很多(我想Table1使用的* 1 *)。儘管如此,你的'.Include()'解決了這個問題。謝謝! –

+0

未來谷歌瀏覽器:請看這裏http://msdn.microsoft.com/en-us/library/bb896272.aspx –

0

。首先可能不會返回任何東西。你確定SomeProperty的值存在於你的數據集的SomeColumn中嗎?

裹在整個事情,如果使用。任何(),以確定是否有一個記錄,或者測試空的resultSet.Table2

+0

如果是這樣,那麼這是一個錯誤。如果序列爲空,首先應該拋出。 –

+0

不,正如我所說,除了表2,這是null的結果集的所有屬性爲空 –