使用 LINQ 在多个条件下加入 table,始终显示主键的所有结果并合并空值
Join table on multiple conditions with LINQ, always show all results of primary key and coalesce nulls
基本上我是在尝试复制这个查询,它作为一个直接的 SQL 查询工作得很好:
SELECT *
FROM Products p
LEFT OUTER
JOIN EventProducts ep ON ep.Product_index = p.[index]
AND COALESCE(ep.Event_index,'3') = '3'
我有两个相关的 table:
- 产品:有索引等信息
- EventProducts:有 index、Product.index 和 Event.index 和其他信息,包括已售出、已分配等
在我的应用程序视图中,事件已经 selected 并且其索引将具有常量值。我想 select 所有产品,并加入 EventProduct 数据(如果它在数据库中有一个条目)然后将该信息填充到数据网格中。
如果 Product 没有关联的 EventProduct,它应该 return 一个像这样的对象:
{
index = 1,
name = productName,
sold = 0,
allocated = 0
...
}
但如果有关联的 EventProduct 条目,return 对象
{
index = 2,
name = product2Name
sold = 10
allocated = 15
...
}
这是我现在的 LINQ 查询:
var eventProducts = dbContext.Products
.Join(dbContext.EventProducts,
product => new { productIndex = product.index, eventIndex = currentEvent.index },
eventProduct => new { productIndex = eventProduct.Product.index, eventIndex = eventProduct.Event.index },
(product, eventProduct) => new
{
Product = product,
EventProduct = eventProduct
});
此查询总是 returns 0 个对象,而它应该 return 8(对于我的每个产品),即使我的 EventProducts table 当前是空的。
Join
执行内部联接,要执行左联接,您可以切换到 query syntax,如下所示:
var query = from product in dbContext.Products
join eventProduct in dbContext.EventProducts.Where(ep => ep.Event_index == currentEvent.index)
on product.index equals eventProduct.Product_index into gj
from sub in gj.DefaultIfEmpty()
select new { Product, EventProduct = sub };
或在 this 答案中使用 GroupJoin
。
或者,如果 Product
实体已正确设置导航,您可以尝试将 Include
与 Where
子句一起使用,看起来像这样(但不确定它是否有效,不能检查 ATM):
var productWithEventProducts = dbContext.Products
.Include(p => p.EventProducts)
.Where(p => p.EventProducts.Any(ep => ep.Event_index == currentEvent.index)
|| !p.EventProducts.Any())
.ToList()
基本上我是在尝试复制这个查询,它作为一个直接的 SQL 查询工作得很好:
SELECT *
FROM Products p
LEFT OUTER
JOIN EventProducts ep ON ep.Product_index = p.[index]
AND COALESCE(ep.Event_index,'3') = '3'
我有两个相关的 table:
- 产品:有索引等信息
- EventProducts:有 index、Product.index 和 Event.index 和其他信息,包括已售出、已分配等
在我的应用程序视图中,事件已经 selected 并且其索引将具有常量值。我想 select 所有产品,并加入 EventProduct 数据(如果它在数据库中有一个条目)然后将该信息填充到数据网格中。
如果 Product 没有关联的 EventProduct,它应该 return 一个像这样的对象:
{
index = 1,
name = productName,
sold = 0,
allocated = 0
...
}
但如果有关联的 EventProduct 条目,return 对象
{
index = 2,
name = product2Name
sold = 10
allocated = 15
...
}
这是我现在的 LINQ 查询:
var eventProducts = dbContext.Products
.Join(dbContext.EventProducts,
product => new { productIndex = product.index, eventIndex = currentEvent.index },
eventProduct => new { productIndex = eventProduct.Product.index, eventIndex = eventProduct.Event.index },
(product, eventProduct) => new
{
Product = product,
EventProduct = eventProduct
});
此查询总是 returns 0 个对象,而它应该 return 8(对于我的每个产品),即使我的 EventProducts table 当前是空的。
Join
执行内部联接,要执行左联接,您可以切换到 query syntax,如下所示:
var query = from product in dbContext.Products
join eventProduct in dbContext.EventProducts.Where(ep => ep.Event_index == currentEvent.index)
on product.index equals eventProduct.Product_index into gj
from sub in gj.DefaultIfEmpty()
select new { Product, EventProduct = sub };
或在 this 答案中使用 GroupJoin
。
或者,如果 Product
实体已正确设置导航,您可以尝试将 Include
与 Where
子句一起使用,看起来像这样(但不确定它是否有效,不能检查 ATM):
var productWithEventProducts = dbContext.Products
.Include(p => p.EventProducts)
.Where(p => p.EventProducts.Any(ep => ep.Event_index == currentEvent.index)
|| !p.EventProducts.Any())
.ToList()