问题:为什么此代码不会将新的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
上的摘要(假设类型包含Id
和Summary
属性...我们将调用此实例{{1} }),从“旧摘要”到“新摘要”。
所以changedWidget
会被这样调用:
UpdateOrInsertWidget
调用UpdateOrInsertWidget(changedWidget);
后,数据库(SQL Server 2008)在“摘要”列中显示“旧摘要”。
_context.SaveChanges();
行似乎在传入时会覆盖entity = (T) entry.Entity;
,这似乎很糟糕。
但是,如果没有更多EF经验,我很难弄清楚这段代码需要改变的地方。
答案 0 :(得分:2)
我认为这里的问题是您的扩展方法只是将ObjectStateEntry
设置为“已修改”状态,但ObjectStateEntry
不知道有什么改变。
您应该使用的是ApplyOriginalValues
或ApplyCurrentValues
,这两种方法将“分离”对象的更改应用于现有ObjectContext
中的对象状态条目并进行比较更改,以便ObjectContext
知道哪些特定属性已更改。
如果您将已更改的实体附加到上下文,则需要ApplyOriginalValues
以便上下文可以查看从原始内容到现在内容的更改内容。否则,您需要使用ApplyCurrentValues
。
您可以在此处阅读更多内容:http://msdn.microsoft.com/en-us/library/bb896248.aspx