Ich verwende Entity Framework 5 ( DBContext
) und versuche, den besten Weg zu finden, um eine Entität tief zu kopieren (dh die Entität und alle zugehörigen Objekte zu kopieren) und dann die neuen Entitäten in der Datenbank zu speichern. Wie kann ich das machen? Ich habe versucht, Erweiterungsmethoden wie zu verwenden CloneHelper
, bin mir aber nicht sicher, ob dies zutrifft DBContext
.
74
Antworten:
Eine billige und einfache Möglichkeit, eine Entität zu klonen, besteht darin, Folgendes zu tun:
Der Trick hier ist AsNoTracking (). Wenn Sie eine Entität wie diese laden, weiß Ihr Kontext nichts davon und wenn Sie SaveChanges aufrufen, wird sie wie eine neue Entität behandelt.
Wenn Sie
MySet
einen Verweis auf habenMyProperty
und auch eine Kopie davon möchten, verwenden Sie einfach FolgendesInclude
:quelle
DirectCast(DbContext, IObjectContextAdapter).ObjectContext.AddObject(entitySetName, entity)
dbContext,Select(x=> { a = x, ab = x.MyCollection.Where(g=>g.Id>2)}).ToList()
Wenn ich hinzufüge,AsNoTracking()
gibt es einen Datenverlust durch die Abfrage..Include("MyProperty.MyNestedObjet")
Siehe msdn.microsoft.com/query/…Guid
IDs geben?Hier ist eine weitere Option.
Ich bevorzuge es in einigen Fällen, weil Sie keine spezielle Abfrage ausführen müssen, um Daten zum Klonen zu erhalten. Mit dieser Methode können Sie Klone von Entitäten erstellen, die Sie bereits aus der Datenbank erhalten haben.
//Get entity to be cloned var source = Context.ExampleRows.FirstOrDefault(); //Create and add clone object to context before setting its values var clone = new ExampleRow(); Context.ExampleRows.Add(clone); //Copy values from source to clone var sourceValues = Context.Entry(source).CurrentValues; Context.Entry(clone).CurrentValues.SetValues(sourceValues); //Change values of the copied entity clone.ExampleProperty = "New Value"; //Insert clone with changes into database Context.SaveChanges();
Diese Methode kopiert die aktuellen Werte aus der Quelle in eine neue Zeile, die hinzugefügt wurde.
quelle
SetValues
funktioniert nicht, wenn das neue Objekt nicht an den Kontext angehängt ist. Es wird eineInvalidOperationException
Ausnahme ausgelöst . Wenn Sie die Entität nur in einem getrennten Zustand klonen möchten, können Sie die Entität zum Kontext hinzufügen, ihre aktuellen Werte festlegen und sie dann trennen.Dies ist eine generische Erweiterungsmethode, die das generische Klonen ermöglicht.
Sie müssen
System.Linq.Dynamic
aus Nuget holen .Das einzige, was Sie selbst implementieren müssen, ist die GetKeyName-Methode. Dies kann alles von
return typeof(TEntity).Name + "Id"
bis seinreturn the first guid property
oder die erste mit gekennzeichnete Eigenschaft zurückgebenDatabaseGenerated(DatabaseGeneratedOption.Identity)]
.In meinem Fall habe ich meine Klassen bereits mit markiert
[DataServiceKeyAttribute("EntityId")]
quelle
Ich hatte das gleiche Problem in Entity Framework Core, wo Deep Clone mehrere Schritte umfasst, wenn untergeordnete Entitäten faul geladen werden. Eine Möglichkeit, die gesamte Struktur zu klonen, ist die folgende:
Natürlich gibt es Möglichkeiten, generische Funktionen zu erstellen, um alles eifrig zu laden und / oder Werte für alle Tasten zurückzusetzen, aber dies sollte alle Schritte klar und anpassbar machen (z. B. alle, damit einige Kinder überhaupt nicht geklont werden, indem sie übersprungen werden Einschließen).
quelle