gpt4 book ai didi

c# - 为什么 Entity Framework 会检测已修改但已重置的属性的更改?

转载 作者:行者123 更新时间:2023-11-30 14:16:05 24 4
gpt4 key购买 nike

如果我修改了 POCO 实体的属性,但将其重置,EntityFramework 仍会提示有更改。

Property "Name": Value "Test" (original value) 
-> Value "Test123" (value changed by UI)
-> Value "Test" (value changed by UI to original value)

已修改的条目:

var objectStateEntries = 
_db.ObjectStateManager.GetObjectStateEntries(
EntityState.Added |
EntityState.Deleted |
EntityState.Modified);

你是怎么处理这个案子的?

最佳答案

如果您的所有属性都是虚拟,默认情况下 Entity Framework 将自动创建您的 POCO 的动态代理。如果我没记错的话,在这种情况下,更改跟踪基于此动态对象的属性 setter ,大致如下:

private string _name;
public string Name
{
// ...
set
{
// if (_name != value) such a check probably does not happen
{
_name = value;
MarkPropertyAsModified(...);
}
}
}

因此,不与原始值进行比较,而仅与属性的当前值进行比较。如果此值发生更改,则无论您是否将其重置为原始值,该属性都会标记为已修改。

(上一段的编辑和更正:如果调用 setter,属性将标记为已修改,无论是否分配了相同或更改的值。感谢 Brad Thomas 和他的评论下面!)

您可以通过在上下文选项中禁用它来避免创建动态代理:

objectContext.ContextOptions.ProxyCreationEnabled = false;

变更检测现在将依赖于快照创建,这意味着 EF 在调用变更检测时将原始值(存储在对象上下文中的快照中)与当前值进行比较。这不再发生在属性 setter 中,而是发生在 Entity Framework 的某些函数中,例如在 SaveChanges 中。在您的情况下,这意味着当您调用 SaveChanges 时,原始值(快照)和当前值将相同,因为您确实重置了更改。基本上 EF 没有注意到您两次更改属性并认为该属性未更改。

请注意,禁用代理创建 - 如果您在全局范围内执行此操作,例如在上下文构造函数中 - 可能会对您的应用程序产生深远的影响。您可能拥有依赖动态代理才能正常工作的代码,并且它还会在各种情况下严重影响性能。存在动态代理以快速进行更改跟踪。基于快照的更改跟踪要慢得多。

关于c# - 为什么 Entity Framework 会检测已修改但已重置的属性的更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8330852/

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