为什么EF没有坚持新的价值?

时间:2011-10-07 18:53:39

标签: c# entity-framework-4 persistence insert-update

问题:为什么此代码不会将新的Summary值保存到数据库中?如果我省略了任何周围/相关代码,请告诉我。

详细信息:

我对EF的实践经验非常少,而且我刚刚继承了一个广泛使用它的代码库。此扩展方法位于该代码库中,其用法如下:

public static void SafeAttachTo<T>(this ObjectContext context, string entitySetName, ref T entity) where T : IEntityWithKey {
            ObjectStateEntry entry; 
            bool attach;

            if (context.ObjectStateManager.TryGetObjectStateEntry(context.CreateEntityKey(entitySetName, entity), out entry)) {
                attach = entry.State == EntityState.Detached;
                entity = (T) entry.Entity;
            }
            else
                attach = true;

            if (attach) 
                context.AttachTo(entitySetName, entity);
        }

用法:

    public int UpdateOrInsertWidget(Widget widget) {
        if (widget.Id == 0) {
            _context.Widgets.AddObject(widget);
        } else {
            _context.SafeAttachTo("Widgets", ref widget);
            _context.ObjectStateManager.ChangeObjectState(widget, EntityState.Modified);
        }

        return _context.SaveChanges();
    }

在某些时候,用户更改Widget上的摘要(假设类型包含IdSummary属性...我们将调用此实例{{1} }),从“旧摘要”到“新摘要”。

所以changedWidget会被这样调用:

UpdateOrInsertWidget

调用UpdateOrInsertWidget(changedWidget); 后,数据库(SQL Server 2008)在“摘要”列中显示“旧摘要”。

_context.SaveChanges();行似乎在传入时会覆盖entity = (T) entry.Entity;,这似乎很糟糕。

但是,如果没有更多EF经验,我很难弄清楚这段代码需要改变的地方。

1 个答案:

答案 0 :(得分:2)

我认为这里的问题是您的扩展方法只是将ObjectStateEntry设置为“已修改”状态,但ObjectStateEntry不知道有什么改变。

您应该使用的是ApplyOriginalValuesApplyCurrentValues,这两种方法将“分离”对象的更改应用于现有ObjectContext中的对象状态条目并进行比较更改,以便ObjectContext知道哪些特定属性已更改。

如果您将已更改的实体附加到上下文,则需要ApplyOriginalValues以便上下文可以查看从原始内容到现在内容的更改内容。否则,您需要使用ApplyCurrentValues

您可以在此处阅读更多内容:http://msdn.microsoft.com/en-us/library/bb896248.aspx