Entity Framework 4.1 Code First中的Multipleactiveresultsets

Rah*_*han 14 .net sql-server entity-framework connection-string ef-code-first

这是我的第一个EF项目,请耐心等待.

更新像Department这样的实体时,将其从上下文中拉出,更新其值并调用context.SaveChanges.但是,如果您更新Department.Employees,EF并不觉得有趣.

我搜索并想出了在连接字符串中设置Multipleactiveresultsets = true的选项,但想知道是否:

  • 这是推荐的方式吗?
  • 这会对性能造成不利影响/我应该注意什么?

Lad*_*nka 35

仅当您要在同一连接上并行执行多个查询时,才需要启用MARS.如果您执行以下操作会发生这种情况:

/* Foreach uses an iterator over the resultset of your query, but the query is not fetched
   immediately, instead the iterator internally triggers fetching for single
   processed record from opened data reader. Because of that the query and the reader
   are active until the iteration is over. */
foreach (var department in context.Departments.Where(...))
{
    /* The first query is still active on the connection but now you are executing
       lazy loading of all related employees =>. You are executing a second query and,
       without MARS, you will get an exception. */
    var employee = department.Employees.FirstOrDefault(...);
}
Run Code Online (Sandbox Code Playgroud)

怎么避免呢?

  • 使用预先加载而不是延迟加载: context.Departments.Include(d => d.Employees)
  • 在使用延迟加载之前实现整个部门的结果集.这意味着不能访问循环内的员工.
  • 启用MARS,上述示例将起作用

这是推荐的方式吗?这会对性能造成不利影响/我应该注意什么?

这取决于您要解决的问题.如果要处理多个部门,则访问其员工集合将触发每个部门的单独查询.这称为N + 1问题 - 您有N个部门和一个查询来获取它们,对于每个部门,您将执行一个额外的查询=> N + 1个查询.对于大量的部门来说,这将是一个性能杀手.

渴望加载也不是防弹解决方案.它也会影响性能.有时,您只需要执行单独的查询来获取所有必要的部门,并单独查询以获取所有必要的员工.如果您关闭延迟加载,它应该修复您的关系并正确填写Employees属性.顺便说一句,我在Data UserVoice上提出了一个开箱即用的功能.