2011-04-29 18 views
2

我想實現這個查詢:我可以使用FirstOrDefault()或第()內凡()

data.Where(d => d.ObjectsA != null && 
    d.ObjectsA.First().ObjectsB != null && 
    d.ObjectsA.First().ObjectsB().First().Nr == 1) 
在Nhibernate.Linq

,但我有一個錯誤。 當我刪除來自Where()的First()都工作。 我試試這個解決方案,但是這並沒有得到我所需要的。

data.Where(d => d.ObjectsA.Where(a.ObjectsB.Where(b=>b.Nr == 1).Any()).Any()); 

我可以在Where()中使用FirstOrDefault()或First()嗎?

編輯:在我的數據庫表中,這個例子中的所有行都沒有空值。

+0

.While()?我沒有看到它 – sehe 2011-04-29 15:21:01

回答

3

First()如果集合爲空則會拋出異常。在您的通話Where()使用Any()確實應該解決的問題,但你會寫是這樣的:

data.Where(d => d.ObjectsA != null && d.ObjectsA.Any() 
    && d.ObjectsA.First().ObjectsB != null && d.ObjectsA.First().ObjectsB.Any() 
    && d.ObjectsA.First().ObjectsB.First().Nr == 1); 

這不是很漂亮,因爲First()最終被稱爲在相同的數據多次。我建議增加一個機構,您的lambda表達式,並使用中間變量與FirstOrDefault()

data.Where(d => { 
    if (d.ObjectsA != null) { 
     var firstA = d.ObjectsA.FirstOrDefault(); 
     if (firstA != null && firstA.ObjectsB != null) { 
      var firstB = firstA.ObjectsB.FirstOrDefault(); 
      if (firstB != null) { 
       return (firstB.Nr == 1); 
      } 
     } 
    } 
    return false; 
}); 

編輯:上面顯然第二個代碼片段不與LINQ工作,NHibernate的。如果你可以使用查詢語法,不具備檢查ObjectsAObjectsBnull,你可以寫:

from d in data 
let firstA = d.ObjectsA.FirstOrDefault() 
let firstB = (firstA != null ? firstA.ObjectsB.FirstOrDefault() : null) 
where (firstB != null && firstB.Nr == 1) 
select d; 
+0

錯誤:帶有語句正文的lambda表達式無法轉換爲表達式樹 – Artiom 2011-04-29 15:12:10

+0

@Artiom,哎,我忘了那個細節。所以看起來你沒有別的選擇,只能使用LINQ to NHibernate的第一個代碼示例,即使反覆調用'First()'似乎看起來不正確...... – 2011-04-29 15:15:36

+0

不幸的是。但是爲什麼Where()在我使用First或FirstOrDefault()時拋出異常?我沒有空集合。 – Artiom 2011-04-29 15:20:25

1

如果在條件中使用集合可以是空的,你可以使用默認的變量和??帶FirstOrDefault()的nullif運算符。

var defaultA = new ObjectA(); 
var defaultB = new ObjectB(); 
var defaultBList = new List<ObjectB>(); 

data.Where(d => d.ObjectsA != null && 
    ((d.ObjectsA.FirstOrDefault() ?? defaultA).ObjectsB ?? defaultBList) 
    .FirstOrDefault() ?? defaultB).Nr == 1)