0

I'm trying to copy an entity like described here. In my entity-wrapper base-class I have the following code to copy/clone an entity.

public TBaseEntityModel Clone(TPrimaryKey newPrimaryKey)
{
    var newEntity = Activator.CreateInstance<TEntity>();
    var clone = DbContext.Entry(newEntity);
    clone.State = EntityState.Added;
    DbContext.Entry(newEntity).CurrentValues.SetValues(TheEntity);
    clone.State = EntityState.Detached;
    var cloneEntityModel= (TBaseEntityModel)Activator.CreateInstance(typeof(TBaseEntityModel), DbContext, newEntity);
    cloneEntityModel.PrimaryKeyValue = newPrimaryKey;
    return cloneEntityModel;
}

After I call the Clone-method on my concrete entity, it has also it's new Primary Key set to the given value of newPrimaryKey.

The propblem occurs when I call SaveChanges() on the underlying context.

It then throws:

Violation of PRIMARY KEY constraint '...'. Cannot insert duplicate key in object 'dbo....'. The duplicate key value is (553a7aa9-0ac2-40a0-820f-43a3b4af745f).

But when I look at my clone, the PK is set to another value. So I guess it is something inside the ObjectContext or even deeper inside.

But I have no idea how to get away the error.

Community
  • 1
  • 1
KingKerosin
  • 3,639
  • 4
  • 38
  • 77
  • What happens in the constructor of `TBaseEntityModel`? – Gert Arnold Apr 25 '16 at 20:15
  • It only sets the properties `DbContext` and `TheEntity` which both are used in the `Clone` method. It also sets a boolean flag which will set the State of the entity to `Added` before the `SaveChanges()`. Maybe there is the issue? – KingKerosin Apr 25 '16 at 20:23
  • Very hard to tell without all these invisible moving parts. Anyway, I wouldn't give an entity a reference to a context. A Clone method should do simply that: create a clone. It shouldn't be involved in the clone's state. – Gert Arnold Apr 25 '16 at 20:32

1 Answers1

0

I suspect that the database is trying to generate the primary key, but you are also trying to specify it explicitly before saving. If you want to specify values for identity columns then you need to jump through some hoops (How can I force entity framework to insert identity columns?). Otherwise, just don't set the value and it will be generated for you when you perform the insert.

Community
  • 1
  • 1
DVK
  • 2,726
  • 1
  • 17
  • 20
  • It's definitely not the database generating the pk. Using `DbContext.Set().Add(new MyEntity{Primary = Guid.NewGuid()});` would work fine. So, specifying it explicitly is not an issue. I still think that EF is keeping a refernce to the 'old' key which crashes on insert for the cloned entity – KingKerosin Apr 25 '16 at 20:12