使用Entity Framework在单个事务中添加和更新相同的实体

时间:2014-09-03 16:11:30

标签: c# entity-framework nhibernate

我有代码接收要执行的操作列表。此列表可以包含“添加新”对象,并且在此“更新”此实体操作之后。代码示例:

     public void RunBulk(IList<BulkItem> bulk)
     {
        using (var transaction = _dbContext.Database.BeginTransaction())
        {
            try
            {
                foreach (var bulkItem in bulk)
                {
                    var entity = bulkItem.Item;
                    if (entity != null)
                    {
                        var entityType = entity.GetType();
                        switch (bulkItem.Operation)
                        {
                            case BulkOperation.Update:
                                {
                                    _dbContext.Entry(entity).State = EntityState.Modified;
                                    _dbContext.Set(entityType).Attach(entity);
                                    break;
                                }
                            case BulkOperation.Write:
                                _dbContext.Set(entityType).Add(entity);
                                break;
                         }
                    }
                }
                _dbContext.SaveChanges();
                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
            }
        }
    }

当调用SaveChanges()时,我得到

  

成功提交了对数据库的更改,     但更新对象上下文时发生错误。     ObjectContext可能处于不一致状态。     内部异常消息:保存或接受更改     失败,因为多个类型的实体     'MyType'有     相同的主键值。确保明确设置主要     关键值是唯一的。确保数据库生成的主数据库     密钥在数据库和中正确配置     实体框架模型。使用实体设计器进行数据库     First / Model First配置。使用'HasDatabaseGeneratedOption'     用于Code First配置的流畅API或“DatabaseGeneratedAttribute”。

数据库中的表没有标识或计算字段,因此应该手动指定它们。

有没有办法“正确”执行这种类型的操作而不会出现异常?

UPD:我有一段使用NHibernate的代码。是否可以使用EF获得相同的功能?

UPD2:可能我需要模拟nhibernate Merge()方法。我在EntityFramework中看到了 AddOrUpdate()方法,但由于某些原因它不适用于我。 Entity Framework Code First AddOrUpdate method insert Duplicate values

    switch (bulkItem.Operation)
        {
            case BulkOperation.Remove:
                nhibernateSession.Delete(nhibernateSession.Merge(entry));
                break;
            case BulkOperation.Write:
            case BulkOperation.Update:
                if (retries > 0 || _useMerge)
                    nhibernateSession.Merge(entry);
                else
                {
                    try
                    {
                        nhibernateSession.SaveOrUpdate(entry);
                    }
                    catch (HibernateException)
                    {
                        nhibernateSession.Merge(entry);
                    }
                }
                break;
            default:
                break;
        }

0 个答案:

没有答案