使用附加方法时 EF 6 OriginalValues 丢失

Posted

技术标签:

【中文标题】使用附加方法时 EF 6 OriginalValues 丢失【英文标题】:EF 6 OriginalValues lost when using Attach method 【发布时间】:2014-07-20 16:42:45 【问题描述】:

我的实体有以下更新通用方法:

public void Update < T > (T entity) where T: class 
    DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
    if (dbEntityEntry.State == System.Data.Entity.EntityState.Detached) 

        DbContext.Set < T > ().Attach(entity);

    
    dbEntityEntry.State = System.Data.Entity.EntityState.Modified;

SaveChanges()后数据库中的数据更新成功。

现在我需要在SaveChanges() 之前实施和审核日志,但我注意到CurrentValues 等于OriginalValues

// For updates, we only want to capture the columns that actually changed
if (!object.Equals(dbEntry.OriginalValues.GetValue<object>(propertyName), dbEntry.CurrentValues.GetValue<object>(propertyName)))

  //here I add a new Audit Log entity


关于如何解决这个问题的任何线索?或者在 Entity Framework 6 中有更好的方法吗?

【问题讨论】:

【参考方案1】:

如果您使用的是断开连接的实体,您可以设置原始值而不影响实体实例值,根据需要调整此方法

public static void LoadOriginalValues(this WorkflowsContext db, DbEntityEntry entity) 
        
            var props = entity.GetDatabaseValues();

            foreach (var p in props.PropertyNames)
            
                if (entity.Property(p).IsModified)
                
                    entity.Property(p).OriginalValue = props[p];
                
            
          

【讨论】:

谢谢,这对我有用。我正在使用审核并检查值。使用附加时,原始值等于使用附加时的当前值。现在使用 entity.getdatabasevalues 工作正常。【参考方案2】:

原始值是从实体本身恢复的。如果实体被上下文跟踪,则此信息可用。

在您的情况下,您使用的是断开连接的实体,因此没有更改跟踪,并且该实体没有原始值。

所以,在这种情况下,如果您需要原始值,除了从数据库中获取它们并一一比较之外,别无选择。

如果您想获得一个表现得好像它已被上下文跟踪的实体,您可以使用上下文从数据库中读取实体,并使用ValueInjecter 之类的东西自动设置断开连接的属性值实体进入被跟踪实体。

【讨论】:

你完全正确!!我需要从数据库中获取原始实体,然后进行比较。不知道这是否会降低应用的性能。 当然,它更慢:你两次访问数据库,这相对昂贵。但是,如果您没有该问题,请不要担心应用程序性能。换句话说:如果您没有性能问题,请不要花任何时间来提高性能。你宁愿重新利用那段时间来实现特性。如果您认为这是正确的答案,请接受它。

以上是关于使用附加方法时 EF 6 OriginalValues 丢失的主要内容,如果未能解决你的问题,请参考以下文章

csharp 使用EF(附加方法).cs更新单个实体

使用 EF Core 保存附加实体时如何删除子实体

在 EF Core DbContext 中,附加方法不起作用

EF Core 在对现有查询添加查询时附加所有实体 [重复]

EF6基础系列(九)--- 附加离线实体图集到上下文

6种方法教你更好的使用EF Core构建应用程序