Jef*_*ege 5 c# sql-server entity-framework lazy-loading
我有一个查询,它连接两个在Entity Framework中没有已定义关系的表,并且连接表具有到第三个表的一对多导航属性.
msg和job之间存在一对多关系,但没有外键,并且.EDMX中没有定义关联.
作业和锁之间存在一对多关系,并且.EDMX中定义了关联,因此作业具有job.locks导航属性,并且lock具有lock.job导航属性.
我的原始查询:
var msgsAndJobs = (
from m in dbContext.msgs
join j in dbContext.jobs
on new { jobid = m.jobid, priority = m.priority }
equals new { jobid = j.jobid, priority = j.priority }
where m.msgtype == "EMERGENCY"
orderby new { m.recvdt }
select new { m, j }
);
Run Code Online (Sandbox Code Playgroud)
我发现EF正在为连接生成一个查询,然后执行第二个查询来为连接返回的每个记录填充导航属性.
微软的文档解释了这个问题:https://msdn.microsoft.com/en-us/data/jj574232.aspx
所以我认为我可以使用.Include()子句来急切地加载所涉及的记录.但它似乎没有工作:
我的新查询:
var msgsAndJobs = (
from m in dbContext.msgs
join j in dbContext.jobs.Include("locks")
on new { jobid = m.jobid, priority = m.priority }
equals new { jobid = j.jobid, priority = j.priority }
where m.msgtype == "EMERGENCY"
orderby new { m.recvdt }
select new { m, j }
);
Run Code Online (Sandbox Code Playgroud)
它仍然为每个作业锁生成一个查询.
我有什么想法我做错了吗?
这就是问题所在Include.使它无效是太容易了,并不总是清楚为什么它不起作用.打破一个问题的Include是改变查询的形状.另一个是投射到非实体类型或匿名类型.
这似乎令人难以置信地预测何时有效Include和无效,但有一个简单的诀窍:Include如果您在查询结束时应用它,则始终有效.
如果你不能在那里申请,那么无论如何都不会有效.
考虑到这一点,如果我们看一下你的情况,很明显为什么Include不起作用.你做不到
(... select new { m, j }).Include("locks"); // Runtime error
Run Code Online (Sandbox Code Playgroud)
因为locks它不是匿名类型的导航属性,显然.如果你使用lambda版本更明显:
(... select new { m, j }).Include(x => x.locks); // Doesn't compile
Run Code Online (Sandbox Code Playgroud)
所以你Include是无效的,locks按需加载.
幸运的是,由于关系修正,存在一条出路,即EF通过其导航属性将实体编织在上下文中的过程.将您的查询更改为:
var msgsAndJobs = (
from m in dbContext.msgs
join j in dbContext.jobs
on new { jobid = m.jobid, priority = m.priority }
equals new { jobid = j.jobid, priority = j.priority }
where m.msgtype == "EMERGENCY"
orderby new { m.recvdt }
select new { m, j, j.locks }
).AsEnumerable()
.Select(x => new { x.m, x.j });
Run Code Online (Sandbox Code Playgroud)
如果执行此查询,.AsEnumerable()则会将结果加载到上下文中,之后您可以选择最初想要的结果.现在您将注意到EF已填充所有job.locks集合.
但重要的是:您必须禁用延迟加载,否则寻址job.locks集合仍将触发延迟加载.这是因为,即使填充了集合,它也不会在Loaded内部标记.
| 归档时间: |
|
| 查看次数: |
954 次 |
| 最近记录: |