LINQ到实体 - 空引用

时间:2010-03-15 14:46:44

标签: c# linq null linq-to-entities

我可以发誓这是前几天的工作:

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到实体只是做错了。

2 个答案:

答案 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