Meh*_* JM 10 c# linq entity-framework
考虑遵循LINQ查询:
var item = (from obj in _db.SampleEntity.Include(s => s.NavProp1)
select new
{
ItemProp1 = obj,
ItemProp2 = obj.NavProp2.Any(n => n.Active)
}).SingleOrDefault();
Run Code Online (Sandbox Code Playgroud)
这按预期运行,但item.ItemProp1.NavProp1为NULL.正如它在这里解释的那样,这是因为查询在使用后实际发生了变化Include().但问题是这种情况的解决方案是什么?
当我像这样更改查询时,每件事都可以正常工作:
var item = (from obj in _db.SampleEntity.Include(s => s.NavProp1)
select obj).SingleOrDefault();
Run Code Online (Sandbox Code Playgroud)
关于这篇文章,我想问题是什么......但作者提供的解决方案不适用于我的情况(因为在最终选择中使用匿名类型而不是实体类型).
Ger*_*old 53
如您所述,Include仅在查询的最终结果包含应包含Include-d导航属性的实体时才有效.
所以在这种情况下Include有效:
var list = _db.SampleEntity.Include(s => s.NavProp1).ToList();
Run Code Online (Sandbox Code Playgroud)
SQL查询将包含一个,JOIN并且每个都SampleEntity将NavProp1加载它.
在这种情况下它没有效果:
var list = _db.SampleEntity.Include(s => s.NavProp1)
.Select(s => new { s })
.ToList();
Run Code Online (Sandbox Code Playgroud)
SQL查询甚至不包含一个JOIN,EF完全忽略了Include.
如果在后一个查询中你希望SampleEntitys包含它们的NavProp1s,你可以这样做:
var list = _db.SampleEntity
.Select(s => new { s, s.NavProp1 })
.ToList();
Run Code Online (Sandbox Code Playgroud)
现在,Entity Framework已经分别从数据库中获取了SampleEntitys和NavProp1实体,但它通过一个名为relationship fixup的进程将它们粘合在一起.如您所见,Include没有必要实现这一目标.
但是,如果Navprop1是一个集合,你会注意到......
var navprop1 = list.First().s.Navprop1;
Run Code Online (Sandbox Code Playgroud)
...仍然会执行一个查询以Navprop1通过延迟加载来获取.这是为什么?
虽然关系修正确实填充Navprop1属性,但它不会将它们标记为已加载.这仅在Include加载属性时发生.所以现在我们SampleEntity都拥有自己的Navprop1s,但是如果不触发延迟加载就无法访问它们.你唯一能做的就是防止这种情况发生
_db.Configuration.LazyLoadingEnabled = false;
var navprop1 = list.First().s.Navprop1;
Run Code Online (Sandbox Code Playgroud)
(或通过禁用代理创建或不Navprop1虚拟来防止延迟加载.)
现在你Navprop1没有新的查询.
对于参考导航属性,这不适用,延迟加载在启用时不会触发.
在实体框架核心中,这方面的情况发生了巨大变化.类似的查询_db.SampleEntity.Include(s => s.NavProp1).Select(s => new { s })现在将包含NavProp1在最终结果中.EF-core在最终结果中寻找"Includable"实体更为明智.因此,我们不会倾向于形成一个查询Select(s => new { s, s.NavProp1 }),以便填充导航属性.要知道,虽然,那如果我们用这样的查询不 Include懒加载仍将被触发时s.NavProp1被访问.
| 归档时间: |
|
| 查看次数: |
16239 次 |
| 最近记录: |