【发布时间】:2013-12-17 08:24:46
【问题描述】:
我的数据模型有一个实体 Person 和 3 个相关 (1:N) 实体 Jobs、Tasks 和 Dates。
我的查询看起来像
var persons = (from x in context.Persons
select new {
PersonId = x.Id,
JobNames = x.Jobs.Select(y => y.Name),
TaskDates = x.Tasks.Select(y => y.Date),
DateInfos = x.Dates.Select(y => y.Info)
}).ToList();
似乎一切正常,但列表JobNames、TaskDates 和DateInfos 并未全部填满。
例如,TaskDates 和 DateInfos 具有正确的值,但 JobNames 保持为空。但是当我从查询中删除TaskDates 时,JobNames 被正确填充。
所以看来 EF 只能处理有限数量的这些“子查询”?它是否正确?如果是这样,最大值是多少。单个语句的这些“子查询”的数量?有没有一种方法可以解决这些问题而无需多次调用数据库?
(ps:我不完全确定,但我似乎记得这个查询在 LINQ2SQL 中有效——可能吗?)
更新
我快疯了。我尝试使用一个全新的简单项目从头开始重现该问题(在此处发布整个代码,而不仅仅是一个过于简单的示例) - 我发现我无法重现它。它仍然发生在我们现有的代码库中(显然这个问题背后还有更多问题,但很遗憾,我不能分享这个封闭的代码库)。
玩了几个小时后,我发现了最奇怪的行为:
- 当我 不
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;在调用 LINQ 语句之前效果很好 - 当我不使用
.Take()只获取前 X 行时,它也很好用(独立于上述) - 当我添加额外的
.Where()语句以减少从 SQL Server 返回的行数时,它也很有效
我没有找到任何可以理解的原因为什么我会看到这种行为,但我开始查看 SQL:虽然 EF 生成完全相同的 SQL,但我使用 READ UNCOMMITTED 时执行计划不同。它在执行计划中间的特定索引上返回 more 行,奇怪的是,它以整个 SQL 语句返回的 less 行结束——这反过来又导致丢失数据,这就是我提出问题的原因。
这听起来很令人困惑和难以置信,我知道,但这是我看到的行为。我不知道还能做什么,我什至不知道在这一点上用谷歌搜索什么 ;-)。
我可以解决我的问题(只是不要使用READ UNCOMMITTED),但我不知道它为什么会发生,以及它是一个错误还是我不知道的关于 SQL Server 的东西。 SQL Server 中可能有一些“子查询中允许的最大结果数”?至少:据我所知,这不是 EF 本身的问题。
【问题讨论】:
-
看
var persons = (from x in context.Persons select new { PersonId = x.Id, JobNames = x.Jobs.Select(y => y.Name), TaskDates = x.Tasks.Select(y => y.Date), DateInfos = x.Dates.Select(y => y.Info) }).ToString(),分析sql。它可能会给这个问题带来一些启示。 -
你能不能试试:JobNames = context.Jobs.Where(j=>j.Person.Id == x.Id).Select(j=>j.Name)
-
我的猜测是 1) 查询需要
MultipleActiveResultSets=True;2) 实体的架构没有正确构建 -
您是否尝试过改用
Include? -
感谢您的建议 - 请参阅上面的更新。
标签: sql-server linq entity-framework