这是我的对象模型。
public class ItemViewModel
{
public Item ItemObject { get; set; }
public IEnumerable<LineItem> Fields { get; set; } = new List<LineItem>();
}
public class Item
{
public int ItemId { get; set; }
public DateTime DatePurchased { get; set; }
}
public class LineItem
{
public int ItemId { get; set; }
public string Name { get; set; }
}
数据库包含 商品 和 订单项 表,对应于对象模型。我正在使用下面编写的 LINQ 表达式来检索
ItemViewModel
对象,提供了一个项目 ID。var i = from i in _dbContext.Items
where i.ItemId == 123
select new ItemViewModel
{
ItemObject = i,
Fields = from field in _dbContext.LineItems
where field.ItemId == i.ItemId
select field
};
var viewModel = await i.SingleOrDefaultAsync();
代码编译正常,但执行后
viewModel.Fields
属性仅包含一个列表项,而在数据库表中针对 ItemID:123 有三个行项。此代码段生成的 SQL(通过 SQL Profiler 捕获)通过 LEFT JOIN 返回三个行项目。这意味着生成的 SQL 很好,但 Entity Framework 的某些方面不太好,但我不知道是什么?
更新:
这是生成的 SQL 查询,它正确地给了我三行:
SELECT
[t].[ItemId], [t].[DatePurchased],
[s0].[ItemId], [s0].[Name]
FROM
(
SELECT
TOP(2) [s].[ItemId], [s].[DatePurchased]
FROM
[Items] AS [s]
WHERE
[s].[ItemId] = 123
) AS [t]
LEFT JOIN [LineItems] AS [s0] ON [t].[ItemId] = [s0].[ItemId]
ORDER BY [t].[ItemId]
技术栈是 .NET Core 3.1 和 Entity Framework Core。
最佳答案
正如 Ivan Stoev 在这个问题下的评论中所建议的那样,原因是 Entity Framework Core 中的一个错误,当将无键实体作为子实体处理时。我通过向我早期的无键表添加主键,然后验证相同的 LINQ 语句来第一手测试它。添加主键后,它开始给我一个包含 3 个项目的列表,而不是只有 1 个。所以在这个问题和我的测试之后,我已将其报告给 EF Core issue tracker .
对于偶然发现这个问题以寻找答案的任何人,我们在这里有两个选择。向无键表添加主键或在 EF 实体模型中定义复合主键。我使用以下行修复了我的情况:
modelBuilder.Entity<LineItem>().HasKey(i => new { i.ItemId, i.Name });
它有效是因为
LineItem.ItemId
和 LineItem.Name
组合对我的实体来说是独一无二的。此答案归功于 an answer (虽然没有正式接受答案)早先的 SO 问题。
关于c# - 为什么此 LINQ 表达式返回只有一项的子列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60610934/