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(),它实际上执行了左连接。你能更新你的答案来解释这一点吗?或者举个例子?对不起,我不在。你需要什么样的例子?