执行左连接和多个内连接时替代嵌套

时间:2013-08-02 21:03:19

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

考虑以下虚构场景:

Entity relationship diagram

即使客户没有订购任何产品,我如何获得每个客户的所有类别(不同或其他,无关紧要)的列表?

还假设我们没有导航属性,因此我们需要使用手动连接。

这是我使用嵌套的尝试:

var customerCategories = from c in context.Customers
                         join o in context.Orders on c.CustomerId equals o.CustomerId into orders
                         select new
                         {
                             CustomerName = c.Name,
                             Categories = (from o in orders
                                           join p in context.Products on o.ProductId equals p.ProductId
                                           join cat in context.Category on p.CategoryId equals cat.CategoryId
                                           select cat)
                         };

是否有不同的(可能更好的方法)来实现相同的结果?

替代方案:多个左(组)联接

var customerCategories = from customer in context.Customers
                         join o in context.Orders on customer.CustomerId equals o.CustomerId into orders
                         from order in orders.DefaultIfEmpty()
                         join p in context.Products on order.ProductId equals p.ProductId into products
                         from product in products.DefaultIfEmpty()
                         join cat in context.Categories on product.CategoryId equals cat.CategoryId into categories
                         select new
                         {
                             CustomerName = c.Name,
                             Categories = categories
                         };

2 个答案:

答案 0 :(得分:2)

我重新创建了你的表结构并添加了一些数据,以便我可以更好地了解你想要做什么。我找到了几种方法来完成你想要的东西,但我只想添加这个方法。我认为这是最简洁的,我认为非常清楚。

<强>代码

var summaries = Customers.GroupJoin(Orders,
    cst => cst.Id,
    ord => ord.CustomerId,
    (cst, ord) => new { Customer = cst, Orders = ord.DefaultIfEmpty() })
    .SelectMany(c => c.Orders.Select(o => new
        {
            CustomerId = c.Customer.Id,
            CustomerName = c.Customer.Name,
            Categories = Categories.Where(cat => cat.Id == c.Customer.Id)
        }));

<强>输出

LINQ Output

表格结构

Table Structure

表格数据

Table Data

答案 1 :(得分:0)

如果您需要所有类别,则不能:

Categories = (from c in context.Category 
                      select cat)