C# 实体框架6:包含嵌套的可空多对多子对象
我的收信人总是空的。虽然我可以在SQL数据库中看到父级和子级之间存在链接C# 实体框架6:包含嵌套的可空多对多子对象,c#,entity-framework,linq,entity-framework-6,C#,Entity Framework,Linq,Entity Framework 6,我的收信人总是空的。虽然我可以在SQL数据库中看到父级和子级之间存在链接 IQueryable<ManageProductItems> models = db.Products .Include(m => m.Collections).Include(m => m.Images) .Include(m => m.VariantDetails.Select(x => x.Variants.Select(z => z.VariantType)
IQueryable<ManageProductItems> models = db.Products
.Include(m => m.Collections).Include(m => m.Images)
.Include(m => m.VariantDetails.Select(x => x.Variants.Select(z => z.VariantType)))
.Select....
SQL server中有一个映射ProductVariantDetailProductVariants
和productVariants
的dbo.ProductVariantDetailProductVariants
表。两个表中的映射ID都是正确的
但这种情况会发生:
Products->VariantDetails->Variants=null
编辑1 我试图用以下方法缩短查询:
var xxx=db.ProductVariantDetails.Include(m=>m.Variants.ToList()代码>
变量正确加载。因此,我确信嵌套的include或bug存在问题
编辑2
这太奇怪了。所以我试着玩代码。我这样说:
var xxx = db.ProductVariantDetails.Include(m => m.Variants.Select(z => z.VariantType)).ToList();
IQueryable<ManageProductItems> models = db.Products
.Include(m => m.Collections).Include(m => m.Images)
.Include(m => m.VariantDetails.Select(x => x.Variants.Select(z => z.VariantType)))
.Select....
var xxx=db.ProductVariantDetails.Include(m=>m.Variants.Select(z=>z.VariantType)).ToList();
IQueryable模型=数据库产品
.Include(m=>m.Collections).Include(m=>m.Images)
.Include(m=>m.VariantDetails.Select(x=>x.Variants.Select(z=>z.VariantType)))
.选择。。。。
因此,xxx
缓存VariantType
然后当models
查询整个实体时,Product->VariantDetails->VariantType
正确加载。如果我只查询模型
而不查询xxx
,问题仍然存在
因此,db
需要先缓存变体
和变体类型
如何解决这个问题?注意:这是第二个答案,它解决了代码中的第二个问题。首先阅读另一个答案,因为我怀疑这将是对你问题最直接的回答
您的Select
正在撤消/忽略您的Include
Include
用于(显式地)隐式自动获取相关实体,但Select
显式地要求不同的返回值,这将覆盖您设置的隐式包含规则
一些示例展示了它的工作原理:
var list = db.Products
.ToList();
这将返回未加载相关实体的产品列表
var list = db.Products
.Include(m => m.ProductOwner)
.ToList();
这将返回同时加载了ProductOwner
属性的产品列表
var list = db.Products
.Select(p => p.Name)
.ToList();
var list2 = db.Products
.Include(m => m.ProductOwner)
.Select(p => p.Name)
.ToList();
两个列表都是字符串列表(带有产品名称)。执行Include
是不相关的
var list = db.Products
.Select(p => p.ProductOwner.Name)
.ToList();
var list2 = db.Products
.Include(m => m.ProductOwner)
.Select(p => p.ProductOwner.Name)
.ToList();
两个列表都是字符串列表(带有productowner名称)。执行Include
是不相关的
var list = db.Products
.Select(p => p.ProductOwner.Name)
.ToList();
var list2 = db.Products
.Include(m => m.ProductOwner)
.Select(p => p.ProductOwner.Name)
.ToList();
这是需要注意的一个重要部分:您不需要Include
来获取相关产品所有者的名称。这是因为您的Select
语句明确要求EF获取相关实体数据,因此EF不需要Include
,因为它不需要隐式加载相关实体
对于任何Select
语句,包括那些仍然使用完整产品
实体的语句,都会维护此行为。这意味着:
var list = db.Products
.Select(p => new { Product = p })
.ToList();
var list2 = db.Products
.Include(m => m.ProductOwner)
.Select(p => new { Product = p })
.ToList();
在这两种情况下,您都将获得产品实体,而不包含其相关的产品所有者
,因为EF侦听选择
,并忽略有关要加载的数据的任何其他说明(包括包含
).注意:这是第二个答案,它解决了代码中的第二个问题。首先阅读另一个答案,因为我怀疑这将是对你问题最直接的回答
您的Select
正在撤消/忽略您的Include
Include
用于(显式地)隐式自动获取相关实体,但Select
显式地要求不同的返回值,这将覆盖您设置的隐式包含规则
一些示例展示了它的工作原理:
var list = db.Products
.ToList();
这将返回未加载相关实体的产品列表
var list = db.Products
.Include(m => m.ProductOwner)
.ToList();
这将返回同时加载了ProductOwner
属性的产品列表
var list = db.Products
.Select(p => p.Name)
.ToList();
var list2 = db.Products
.Include(m => m.ProductOwner)
.Select(p => p.Name)
.ToList();
两个列表都是字符串列表(带有产品名称)。执行Include
是不相关的
var list = db.Products
.Select(p => p.ProductOwner.Name)
.ToList();
var list2 = db.Products
.Include(m => m.ProductOwner)
.Select(p => p.ProductOwner.Name)
.ToList();
两个列表都是字符串列表(带有productowner名称)。执行Include
是不相关的
var list = db.Products
.Select(p => p.ProductOwner.Name)
.ToList();
var list2 = db.Products
.Include(m => m.ProductOwner)
.Select(p => p.ProductOwner.Name)
.ToList();
这是需要注意的一个重要部分:您不需要Include
来获取相关产品所有者的名称。这是因为您的Select
语句明确要求EF获取相关实体数据,因此EF不需要Include
,因为它不需要隐式加载相关实体
对于任何Select
语句,包括那些仍然使用完整产品
实体的语句,都会维护此行为。这意味着:
var list = db.Products
.Select(p => new { Product = p })
.ToList();
var list2 = db.Products
.Include(m => m.ProductOwner)
.Select(p => new { Product = p })
.ToList();
在这两种情况下,您都将获得产品实体,而不包含其相关的产品所有者
,因为EF会侦听选择
,并忽略有关加载哪些数据的任何其他说明(包括包含
)。您缺少一个包含:
db.Products
.Include(m => m.Collections)
.Include(m => m.Images)
.Include(m => m.VariantDetails.Select(x => x.Variants.Select(z => z.VariantType)))
.Select(...);
您从未要求加载变体
本身。如果未加载变体
,则会忽略所有后续相关实体
请尝试以下操作:
db.Products
.Include(m => m.Collections)
.Include(m => m.Images)
.Include(m => m.VariantDetails.Select(x => x.Variants))
.Include(m => m.VariantDetails.Select(x => x.Variants.Select(z => z.VariantType)))
.Select(...);
但是,您可能通过隐藏Select
语句隐藏了第二个问题。我添加了第二个答案来解决这个潜在的次要问题。您缺少一个包含:
db.Products
.Include(m => m.Collections)
.Include(m => m.Images)
.Include(m => m.VariantDetails.Select(x => x.Variants.Select(z => z.VariantType)))
.Select(...);
您从未要求加载变体
本身。如果未加载变体
,则会忽略所有后续相关实体
请尝试以下操作:
db.Products
.Include(m => m.Collections)
.Include(m => m.Images)
.Include(m => m.VariantDetails.Select(x => x.Variants))
.Include(m => m.VariantDetails.Select(x => x.Variants.Select(z => z.VariantType)))
.Select(...);
但是,您可能通过隐藏Select
语句隐藏了第二个问题。我添加了第二个答案来解决这个潜在的次要问题。使用这个答案db.Products.Include(x=>x.VariantDetails)。然后使用Include(v