如何在Entity Framework中保存组合(新建+修改)的分离实体?

Ale*_*sev 6 .net c# entity-framework poco

保存组合的新的和修改的分离POCO实体的正确和快速方法是什么?

我在想这些方法:

    private void Method_2(IList<Entity> entities) //detached entities
    {
        //This method is using SELECT to check if entity exist
        using (var context = new ModelContainer())
        {
            foreach (Entity entity in entities)
            {
                var foundEntity = context.CreateObjectSet<Entity>().SingleOrDefault(t => t.Id == entity.Id);
                context.Detach(foundEntity);    //Remove it from ObjectStateManager

                if (foundEntity != null)//It is modified entity
                {
                    context.AttachTo("EntitySet", entity); //Attach our entity
                    context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified); //We know it exists
                }
                else//It is new entity
                {
                    context.CreateObjectSet<Entity>().AddObject(entity);
                }
            }
            context.SaveChanges();
        }
    }

    private void Method_1(IList<Entity> entities) //detached entities
    {
        //This method doesn't select anything from DB, but i have ta call Savechanges after each object
        using (var context = new ModelContainer())
        {
            foreach (Entity entity in entities)
            {
                try
                {
                    context.AttachTo("EntitySet", entity);
                    context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
                    context.SaveChanges();
                }
                catch (OptimisticConcurrencyException)
                {
                    context.ObjectStateManager.ChangeObjectState(entity, EntityState.Added);
                    context.SaveChanges();
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

当您在分离的环境中工作时,您必须知道添加了哪个实体以及哪些实体已被修改 - 您有责任保留此信息并将其提供给ObjectContext.

好吧,我同意这个说法,如果你发现自己遇到需要在EF中使用这样的EF代码的情况,那么肯定你的决定有问题.我为这份工作选择了错误的工具.

Lad*_*nka 4

当您在分离环境中工作时,您必须知道添加了哪些实体以及修改了哪些实体 - 您有责任保留此信息并将其提供给 ObjectContext。

非常简单的方法是:

foreach (var entity in entities)
{
  if (entity.Id == 0) // 0 = default value: means new entity
  {
    // Add object
  }
  else
  {
    // Attach object and set state to modified
  }
}
Run Code Online (Sandbox Code Playgroud)

该示例要求您有一些数据库自动生成的主键(Id)。

您的方法 2 经过一些修改是可行的。加载实体时不需要分离实体。而是使用ApplyCurrentValues。当您决定使用对象图而不是单个实体时,首先加载实体的方法非常有用。但对于对象图,您必须手动进行同步。ApplyCurrentValues 仅适用于标量(非导航)属性。您可以尝试进一步优化您的方法,以在单次往返数据库中加载所需的实体,而不是一个接一个地加载实体。

你的方法1是一个糟糕的解决方案。使用数据库服务器上引发的异常来控制程序流是不好的方法。