gpt4 book ai didi

c# - 在 EF 中将外键 ID 设置为 null 非常非常慢

转载 作者:太空宇宙 更新时间:2023-11-03 11:22:04 25 4
gpt4 key购买 nike

我正在通过存储库模式使用 Entity Framework,但遇到了一个严重且令人惊讶的性能问题。我已经完成了分析,所以我很清楚会发生什么,我只是不知道该怎么做。

这是我的代码的精髓(简化):

var employee = Repositories.Employees.FirstOrDefault(s => s.EmployeeId == employeeId);
employee.CompanyId = null;
Repositories.Commit();

中间一行 (employee.CompanyId = null) 花费了惊人的时间来完成(大约 30 秒)。时间不花在提交行上。

通过分析,我找到了运行这部分自动生成的 EF 代码的原因:

if (previousValue != null && previousValue.**Employees**.Contains(this))
{
previousValue.Employees.Remove(this);
}

这并没有真正帮助我,但它确实证实了问题出在 EF 上。我真的很想知道该怎么办。我可以通过其他方式(存储过程)更新该列,但我真的宁愿在所有地方都使用 EF。

我无法轻易编辑 EF 设置,所以我更喜欢不涉及此的建议。

更新我通过直接对数据库运行 SQL 然后从上下文刷新对象以确保 EF 会立即检测到此更改来解决这个问题。

public void SetCompanyNull(Guid employeeId)
{
_ctx.ExecuteStoreCommand("UPDATE Employee SET CompanyId = NULL WHERE EmployeeId = N'" + employeeId + "'");
_ctx.Refresh(RefreshMode.StoreWins, _ctx.Employees.FirstOrDefault(s => s.EmployeeId == employeeId));
}

更新 2我还通过暂时禁用延迟加载解决了这个问题。

var lazyLoadDisabled = false;
if (_ctx.ContextOptions.LazyLoadingEnabled)
{
_ctx.ContextOptions.LazyLoadingEnabled = false;
lazyLoadDisabled = true;
}

this.GetEmployeeById(employeeId).CompanyId = null;
this.SaveChanges();

if (lazyLoadDisabled)
{
_ctx.ContextOptions.LazyLoadingEnabled = true;
}

我真的很好奇为什么禁用延迟加载会更快(以及这可能有哪些副作用)

最佳答案

这是 EF POCO 生成器模板中的问题,它会在某些情况下导致意外的延迟加载。此模板为导航属性生成修复代码,因此如果您更改一侧的导航属性,它会在内部转到更改关系的另一端并尝试修复关系以保持一致。不幸的是,如果您的相关对象没有加载导航属性,它会触发延迟加载。

你可以做什么:

  • 修改模板并删除所有与修复相关的代码
  • 从您的 Company 中删除反向导航属性(Employees)
  • 在此操作之前关闭延迟加载 - context.ContextOptions.LazyLoadingEnabled = false

关于c# - 在 EF 中将外键 ID 设置为 null 非常非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10620966/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com