这是我的第一个 EF 项目,请多多包涵。
在更新诸如 Department 之类的实体时,您将其从上下文中拉出,更新其值并调用 context.SaveChanges。但是,如果您更新 Department.Employees,EF 不会觉得这很有趣。
我搜索并想出了在连接字符串中设置 Multipleactiveresultsets=true 的选项,但想知道是否:
- 这是推荐的方式吗?
- 这是否会对性能产生不利影响/我应该注意什么?
这是我的第一个 EF 项目,请多多包涵。
在更新诸如 Department 之类的实体时,您将其从上下文中拉出,更新其值并调用 context.SaveChanges。但是,如果您更新 Department.Employees,EF 不会觉得这很有趣。
我搜索并想出了在连接字符串中设置 Multipleactiveresultsets=true 的选项,但想知道是否:
仅当您想在同一连接上并行执行多个查询时,才需要启用 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(...);
}
如何避免这种情况?
context.Departments.Include(d => d.Employees)
这是推荐的方式吗?这是否会对性能产生不利影响/我应该注意什么?
这取决于您要解决的问题。如果您有多个部门要处理,访问他们的员工集合将触发每个部门的单独查询。这被称为 N+1 问题 - 您有 N 个部门和一个查询来获取它们,并且对于每个部门,您将执行一个额外的查询 => N+1 个查询。对于大量部门来说,这将是一个性能杀手。
急切加载也不是一个防弹解决方案。它也会影响性能。有时您只需要执行单独的查询来获取所有必要的部门,并执行单独的查询来获取所有必要的员工。如果您关闭了延迟加载,它应该会修复您的关系并为您正确填写员工属性。顺便说一句,我对 Data UserVoice 提出了一个建议,即开箱即用地支持此功能。