EF 4:如何更新断开连接的数据集?

时间:2011-05-05 00:52:42

标签: entity-framework-4 poco

我正在使用EF 4,POCO。任务如下:拥有一组DomainObject类型的数据,需要从数据库中获取并在断开连接模式下更新(添加,更新,删除操作)。如何将更新的集合稍后推送回数据库?假设我们加载数据后没有对表进行并行更改。我知道context.SaveChanges()做了更新,但问题是如何将所有更改从有点列表中放回到DbSet,或者可能有一种方法可以在断开模式下直接使用DbSet?谢谢!

2 个答案:

答案 0 :(得分:7)

自跟踪实体是EDMX + ObjectContext API的特性,因此如果您的映射/代码依赖于DbContext API(您提到DbSet),则无法使用它们。自跟踪实体是变更集模式的实现(与旧数据集一样)。关于SO的一些参考:

如果您不使用自我跟踪实体,答案非常简单 - 您必须说EF您做了哪些更改。使用分离的实体后,您必须将实体附加回新的上下文并手动说出您的确切操作=插入,更新,删除的内容以及您如何更改关系。此过程中的关键组件是ObjectContext API中的ObjectStateManagercontext.ObjectStateManager)或DbContext API中的DbChangeTrackercontext.ChangeTracker)。在处理关系时,这是非常困难的,因此我们很多人通常使用另一个进程:我们再次加载实体图并将更改从分离的实体图合并到附加的实体图。一些参考文献:

请注意,根据您要执行的更新次数,整个过程可能会非常慢。原因是EF doesn't support command batching所以每次插入,更新,删除都是在单独的数据库往返中执行的。如果更新100.000复杂对象,则可能需要执行SaveChanges几分钟。

编辑:

在一些非常特殊的情况下,您只使用没有关系的实体,您可以使用技巧来传输有关“更改”的信息:

public void ProcessChanges(IEnumerable<DomainObject> entities)
{
    foreach(var entity in entities)
    {
        if (entity.Id == 0)
        {
            // New entity
        }
        else if (entity.Id > 0)
        {
            // Modified entity (you cannot say if entity war really modified,
            // you must update it always).
        }
        else
        {
            // Use negative Id (origId * -1) to mark entity as deleted
            // reverse Id and delete entity
        }
    }
}

这仅适用于带有简单键的扁平物体。

答案 1 :(得分:-1)