我正在尝试实现这个查询:
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()吗?
编辑:在我的DB表中,这个例子中的所有行都没有空值。
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;
});
EDIT:上面的第二个代码片段显然不能使用LINQ to NHibernate。如果可以使用查询语法,不需要检查ObjectsA
和ObjectsB
是否为null
,可以这样写:
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;
如果条件中使用的集合可以为空,则可以使用默认变量和??使用FirstOrDefault().
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)