注意:我知道Linq的问题存在很多问题.Include(表)没有加载数据,我相信我已经用尽了人们列出的选项,但仍然有问题。
我正在维护的应用程序上有一个很大的Linq2Entities查询。查询构建如下:
IQueryable<Results> query = context.MyTable
.Where(r =>
r.RelatedTable.ID == 2 &&
r.AnotherRelatedTable.ID == someId);
然后根据各种业务逻辑构建谓词,例如:
if (sortColumn.Contains("dob "))
{
if (orderByAscending)
query = query.OrderBy(p => p.RelatedTable.OrderByDescending(q => q.ID).FirstOrDefault().FieldName);
else
query = query.OrderByDescending(p => p.RelatedTable.OrderByDescending(q => q.ID).FirstOrDefault().FieldName);
}
注意 - 始终提供排序顺序。
最初,在阅读了着名的Tip 22之类的文章之后,所包含的表格被设置在开头,所以现在它们在最后完成(这不能解决问题):
var resultsList = (query.Select(r => r) as ObjectQuery<Results>)
.Include("RelatedTable")
.Include("AnotherRelatedTable")
.Skip((page - 1) * rowsPerPage)
.Take(rowsPerPage);
似乎是随机的(大约每5000个网站用户,这个问题发生一次),不会加载RelatedTable数据。可以通过在相关表上调用load来强制强制它。但即使加载失败也不一致,我在测试中运行查询并且它有效,但大部分时间都没有,无需更改任何代码或数据。
很好,当不包括skip和take时,返回整个数据集,但我希望跳过并在完整的数据集上完成 - 它肯定似乎来自分析SQL。 ..
更新16/11/10:我已针对问题数据集分析了SQL,并且我已经能够重现查询失败大约9/10次,但接下来其余的。当查询失败或成功时,正在执行的SQL是相同的,除非正如预期的那样,传递给SQL的参数。
这个问题已经通过以下改变得到了解决,但问题仍然是为什么会这样。
失败 - 让LINQ处理行:
var resultsList = (query.Select(r => r) as ObjectQuery<Results>)
.Include("RelatedTable")
.Include("AnotherRelatedTable")
.Skip((page - 1) * rowsPerPage)
.Take(rowsPerPage)
.ToList();
工作 - 枚举数据,然后获取行:
var resultsList = (query.Select(r => r) as ObjectQuery<Results>)
.Include("RelatedTable")
.Include("AnotherRelatedTable")
.ToList()
.Skip((page - 1) * rowsPerPage)
.Take(rowsPerPage);
不幸的是,这个查询创建的SQL包含一些敏感的架构数据,因此我无法发布它,它也是1400行,所以无论如何我都不会让公众接受它!
答案 0 :(得分:2)
Take()
的唯一影响是更改生成的SQL。除此之外,实体框架根本不关心它。 .Skip()
也是如此。很难相信这会对查询实现产生影响(虽然发生了奇怪的事情)。
那么可能导致这种行为?在我的头顶:
我认为你不会进一步了解这个问题,直到你能够捕获生成的SQL并自己运行它。这实际上并不十分困难,因为您可以使用适当的过滤器设置SQL事件探查器。如果您发现生成的SQL在错误的情况下是不同的,您可以从那里向后工作。如果您发现生成的SQL在错误情况下是相同的,那么下一步将是查看返回的行,最好是在与应用程序运行它相同的上下文中。
简而言之,我认为您必须不断调整SQL分析,直到获得所需信息为止。