Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 执行左连接和多个内部连接时嵌套的替代方法_C#_Linq_Linq To Sql_Linq To Entities - Fatal编程技术网

C# 执行左连接和多个内部连接时嵌套的替代方法

C# 执行左连接和多个内部连接时嵌套的替代方法,c#,linq,linq-to-sql,linq-to-entities,C#,Linq,Linq To Sql,Linq To Entities,考虑以下虚构的场景: 即使客户没有订购任何产品,我如何为每个客户获取所有类别的列表(不同的或其他的,这并不重要) 还假设我们没有导航属性,所以我们需要使用手动连接 这是我使用嵌套的尝试: var customerCategories = from c in context.Customers join o in context.Orders on c.CustomerId equals o.CustomerId into orders

考虑以下虚构的场景:

即使客户没有订购任何产品,我如何为每个客户获取所有类别的列表(不同的或其他的,这并不重要)

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

这是我使用嵌套的尝试:

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
                         };

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

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

我重新创建了您的表结构并添加了一些数据,以便更好地了解您要做的事情。我找到了一些方法来实现你想要的,但我只想添加这个方法。我认为这是最简洁的,而且我认为它非常清楚

代码

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)
        }));
输出

表格结构

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)
        }));

表格数据


这是哪条通向xxx的路?有哪些导航属性?您可能不需要任何手动编写的join子句就可以做到这一点。这是linq to entities,但这并不重要。如果客户没有任何产品,为什么您真的需要加入呢。业务场景可以是获取客户购买的产品类别,也可以获取所有类别。在您的例子中,似乎希望显示所有类别,因此不需要联接。可能有点不清楚,但我使用的示例是虚构的,它的存在纯粹是为了表示左联接,然后是所需的内部联接。内部联接将始终过滤结果。如果您需要一个表(在本例中是一个实体),那么您必须始终从您想要作为一个整体的表开始,然后使用左连接。谢谢,这实际上是完全正确的。我以前确实试过,但运气不好。这次我在组中添加了DefaultIfEmpty(),它实际上执行了左连接。你能更新你的答案来解释这一点吗?或者举个例子?对不起,我不在。你需要什么样的例子?