我正在尝试实现此查询:
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 :(得分: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表达式中添加一个body,并使用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 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;
答案 1 :(得分: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)