4

I have code that receives list of operations to execute. This list can contain "add new" object and right after this "update" this entity operation. Code example:

     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();
            }
        }
    }

When SaveChanges() is called i get

The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: Saving or accepting changes failed because more than one entity of type 'MyType' have the same primary key value. Ensure that explicitly set primary key values are unique. Ensure that database-generated primary keys are configured correctly in the database and in the Entity Framework model. Use the Entity Designer for Database First/Model First configuration. Use the 'HasDatabaseGeneratedOption" fluent API or 'DatabaseGeneratedAttribute' for Code First configuration.

Table in database doesn't have identity or computed fields, so they all should be specified manually.

Is there any way to execute this type of operations "correctly" without getting exception?

UPD: I have working piece of code which uses NHibernate. Is it possible to get same functionality with EF?

UPD2: Probably i need analog for nhibernate Merge() method. I have seen somewhere AddOrUpdate() method in EntityFramework, but for some reason it's not available for me. 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;
        }
Community
  • 1
  • 1
cmd
  • 515
  • 3
  • 9
  • 19
  • My guts say that this has nothing to do with the transaction or doing multiple insert/updates. At the time you attach/add some object, another object with the same primary key is attached to the `ObjectContext`, it could be the same one previously fetched from db. Try using a fresh new `DbContext` at the start of your `RunBulk` method and see if my theory is correct. – mostruash Sep 03 '14 at 16:25
  • These objects are detached from context and BulkOperation.Update and BulkOperation.Write are not operations with database. These operations are performed on another data storage and this piece of code is used to synchronize changes. Basically the question is how can i accumulate all these operations and then save this to DB in one transaction. – cmd Sep 03 '14 at 16:33
  • @cmd Did you get the solution to your problem. I am having trouble with a similar issue. I want to know the solution. Please help if you have solved this. Thank you. – xyzWty Jul 19 '19 at 04:10

0 Answers0