加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 01:49:37 所属栏目:百科 来源:网络整理
导读:如果我修改POCO实体的属性,但重置它,EntityFramework仍然表示存在更改. Property "Name": Value "Test" (original value) - Value "Test123" (value changed by UI) - Value "Test" (value changed by UI to original value) 已修改的条目: var objectState
如果我修改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的动态代理.如果我没有错,那么更改跟踪就是基于这种动态对象的属性设置器,大致如下:

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

因此,没有与原始值进行比较,只能与属性的当前值进行比较.如果此值发生更改,则无论是否将其重置为原始值,属性都会标记为已修改.

(编辑和更正前一段:如果调用了setter,则该属性被标记为Modified,无论是否分配了相同或更改的值.感谢Brad Thomas及其下面的评论!)

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

objectContext.ContextOptions.ProxyCreationEnabled = false;

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

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读