2016-04-25 16 views
0

Ich versuche, eine Entität wie beschrieben here zu kopieren. In meiner Entity-Wrapper-Basisklasse habe ich den folgenden Code zum Kopieren/Klonen einer Entität.Cloning-Entität schlägt mit Primärschlüsselverletzung bei SaveChanges()

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

Nachdem ich die Clone -Methode auf meine konkrete Einheit nennen, hat es auch ist es neue Primary Key Set auf den angegebenen Wert von newPrimaryKey.

Das Problem tritt auf, wenn ich SaveChanges() auf den zugrunde liegenden Kontext aufrufen.

Es wirft dann:

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

Aber wenn ich an meinem clone aussehen wird der PK auf einen anderen Wert eingestellt. Also ich denke, es ist etwas in der ObjectContext oder noch tiefer im Inneren.

Aber ich habe keine Ahnung, wie man den Fehler wegkommt.

+0

Was passiert im Konstruktor von 'TBaseEntityModel'? –

+0

Er setzt nur die Eigenschaften 'DbContext' und' TheEntity', die beide in der 'Clone'-Methode verwendet werden. Es setzt auch ein boolesches Flag, das den Status der Entität vor dem 'SaveChanges()' auf 'Added' setzt. Vielleicht gibt es das Problem? – KingKerosin

+0

Sehr schwer zu sagen ohne all diese unsichtbaren beweglichen Teile. Jedenfalls würde ich einer Entität keinen Verweis auf einen Kontext geben. Eine Clone-Methode sollte einfach Folgendes tun: einen Klon erstellen. Es sollte nicht am Zustand des Klons beteiligt sein. –

Antwort

0

Ich vermute, dass die Datenbank versucht, den Primärschlüssel zu generieren, aber Sie versuchen auch, es explizit vor dem Speichern anzugeben. Wenn Sie Werte für Identitätsspalten angeben möchten, müssen Sie einige Rahmen durchlaufen (How can I force entity framework to insert identity columns?). Andernfalls setzen Sie den Wert einfach nicht und er wird für Sie generiert, wenn Sie die Einfügung durchführen.

+0

Es ist definitiv nicht die Datenbank, die das PK erzeugt. Verwenden von 'DbContext.Set (). Add (neue MyEntity {Primary = Guid.NewGuid()}); würde funktionieren. Es ist also kein Problem, sie explizit anzugeben. Ich denke immer noch, dass EF eine Bezugnahme auf den "alten" Schlüssel beibehält, der beim Einfügen für die geklonte Einheit abstürzt – KingKerosin

Verwandte Themen