我可以发誓这是前几天的工作:
var resultSet =
(from o in _entities.Table1
where o.Table2.Table3.SomeColumn == SomeProperty
select o
).First();
SelectedItem = resultSet.Table2.SomeOtherColumn;
我在最后一行得到一个空引用异常:resultSet.Table2为null
我不仅确定所有外键和其他东西都具有正确的值,而且我不知道Table2 如何为空,因为o.Table2.Table3.SomeColumn == SomeProperty
。
resultSet具有所有正确的值,但Table2为空。
[编辑] 这有效:
SelectedItem = _entities.Table2.First(
o => o.Table2.SomeColumn == SomeProperty).SomeOtherColumn;
而且,上面, resultSet
具有所有正确的值,因此数据库中的数据不存在问题; LINQ到实体只是做错了。
答案 0 :(得分:5)
LINQ-to-entities正在做错事。
不,它按设计工作。当你强制它时,L2E只会在表格中JOIN
。这提高了性能。只要您在L2E中,就可以引用任何关系。这就是为什么这样做的原因:
SelectedItem = _entities.Table2.First(
o => o.Table2.SomeColumn == SomeProperty).SomeOtherColumn;
此处的lambda表达式将由LINQ to Entities解释,并转换为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。)
答案 1 :(得分:0)
。首先可能不会返回任何东西。您确定SomeProperty的值存在于数据集的SomeColumn中吗?
使用.Any()将整个内容包装起来以确定您是否有记录,或者在resultSet上测试null.Table2