【发布时间】:2018-07-12 16:27:55
【问题描述】:
当我期望可以从 EF 缓存中抓取对象时,为什么 Entity Framework 会执行查询?
使用这些简单的模型类:
public class Blog
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
public class Post
{
public int Id { get; set; }
public string Content { get; set; }
public virtual Blog Blog { get; set; }
}
public class BlogDbContext : DbContext
{
public BlogDbContext() : base("BlogDbContext") {}
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
}
我分析以下操作的查询
public class HomeController : Controller
{
public ActionResult Index()
{
var ctx = new BlogDbContext();
// expecting posts are retrieved and cached by EF
var posts = ctx.Posts.ToList();
var blogs = ctx.Blogs.ToList();
var wholeContent = "";
foreach (var blog in blogs)
foreach (var post in blog.Posts) // <- query is executed
wholeContent += post.Content;
return Content(wholeContent);
}
}
为什么 EF 不重新使用我已经通过 var posts = ctx.Posts.ToList(); 语句获取的 Post 实体?
进一步说明:
现有应用程序具有 Excel 导出报告。数据是通过一个包含树的主 Linq2Sql 查询获取的(~20)。然后它通过自动映射器进行映射,并添加来自手动缓存的其他数据(如果添加到主查询中,以前会减慢执行速度)。
现在数据增长了,当尝试执行查询时 SQL Server 崩溃并出现错误:
查询处理器用尽了内部资源,无法生成查询计划。
延迟加载会导致 >100.000 个查询。所以我想我可以通过一些简单的查询来预加载所有需要的数据,并让 EF 在延迟加载期间自动使用缓存中的对象。
我最初在 TSQL IN() 子句的限制方面遇到了其他问题,我通过 MoreLinq 的 Batch 扩展解决了这些问题。
【问题讨论】:
标签: entity-framework linq eager-loading