关于c#:实体的Linq不会为Left Join抛出Null引用异常

Linq to Entities NOT throwing Null reference exception for Left Join

在Linq to Object中:
访问左外部联接结果集的右表对象时,查询将引发Null引用异常。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    var customers = new Customer[]
    {
        new Customer{Code = 5, Name ="Sam"},
        new Customer{Code = 6, Name ="Dave"},
        new Customer{Code = 7, Name ="Julia"},
        new Customer{Code = 8, Name ="Sue"}
    };


    var orders = new Order[]
    {
        new Order{KeyCode = 5, Product ="Book"},
        //new Order{KeyCode = 6, Product ="Game"},
        new Order{KeyCode = 7, Product ="Computer"},
        new Order{KeyCode = 7, Product ="Mouse"},
        new Order{KeyCode = 8, Product ="Shirt"},
        new Order{KeyCode = 5, Product ="Underwear"}
    };

    var query = customers.GroupJoin(orders,
        c => c.Code,
        o => o.KeyCode,
        (customer, order) => new { customer,order})
        .SelectMany(q => q.order.DefaultIfEmpty(),(q,order)=>new{q.customer,order});

    query.Where(l => l.order.Product.Contains("Book")).Dump();

像在SQLServer中一样,假设上述客户和订单数据。 Same Query(即现在与LINQ to EF)未引发空引用异常。它只是返回记录。

Why it is not throwing null reference exception ? Even Order object
for Customer{Code:6, Name:"Dave"} is null

编辑:
我尝试了一些小的变化,如下所示。

1
var result = query.Where(l => l.order.Product.Contains("Book")).ToList();

以上查询未引发Null参考异常

1
var result = query.ToList().Where(l => l.order.Product.Contains("Book"));

此查询引发异常

对具有近50,000条记录的表的两个查询均未引发异常。

在我的生产环境中,进行类似的查询,但是数量级为50,000条记录,而不是4或6条记录。在数据访问层中,我在应用所有Where过滤器后将查询结果作为List返回。没有引发异常,系统运行正常。

Do I need to Check null on Order object in Where Predicate as in
Alex Zaitsev's answer ?


这是由于Linq的懒惰执行行为。实际上,它为null,但是只有在您尝试转换为list时才可见,此时仅执行查询。请尝试转换为如下列表,

1
var result =  query.Where(l => l.order.Product.Contains("Book")).ToList();

您将获得" NullReferenceException"