Linq to Entities不为左连接

时间:2017-09-08 08:41:37

标签: c# entity-framework-6 linq-to-entities left-join

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

    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中假设上面提到的客户和订单数据。相同的查询(即现在为 LINQ to EF )不会抛出空引用异常。它只是返回记录。

  

为什么不抛出null引用异常?甚至是Order个对象   for Customer {代码:6,名称:“Dave”}为空

修改 我尝试了如下几点变化。

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

以上查询未抛出空引用异常

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

此查询抛出异常

桌面上的两个查询都有近50,000条记录没有抛出异常。

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

  

我是否需要在Order谓词中的Where对象上检查null,如下所示   Alex Zaitsev的answer

1 个答案:

答案 0 :(得分:1)

这是因为Linq的惰性执行行为。实际上它是null但只有当你试图转换为list时它才会可见,那时只执行查询。请尝试转换为如下所示的列表,

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

你会得到一个" NullReferenceException"