Entity Framework 5 ( DBContext
) を使用しており、エンティティをディープ コピー (つまり、エンティティとすべての関連オブジェクトをコピー) し、新しいエンティティをデータベースに保存する最良の方法を見つけようとしています。これどうやってするの?などの拡張メソッドの使用を検討しましCloneHelper
たが、 に適用されるかどうかはわかりませんDBContext
。
質問する
45733 次
4 に答える
132
エンティティを複製する安くて簡単な方法の 1 つは、次のようにすることです。
var originalEntity = Context.MySet.AsNoTracking()
.FirstOrDefault(e => e.Id == 1);
Context.MySet.Add(originalEntity);
Context.SaveChanges();
ここでのトリックはAsNoTracking()です。このようにエンティティをロードすると、コンテキストはそれを認識せず、SaveChanges を呼び出すと、それを新しいエンティティのように扱います。
MySet
への参照がMyProperty
あり、そのコピーも必要な場合は、次を使用しInclude
ます。
var originalEntity = Context.MySet.Include("MyProperty")
.AsNoTracking()
.FirstOrDefault(e => e.Id == 1);
于 2013-03-10T12:51:05.737 に答える
23
別のオプションがあります。
場合によっては、データのクローンを取得するためにクエリを実行する必要がないため、好まれます。この方法を使用して、データベースから既に取得したエンティティのクローンを作成できます。
//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();
このメソッドは、ソースから追加された新しい行に現在の値をコピーします。
于 2014-02-12T13:41:40.947 に答える
1
エンティティ フレームワーク コアでも同じ問題がありました。子エンティティが遅延ロードされると、ディープ クローンに複数のステップが含まれます。構造全体を複製する 1 つの方法は次のとおりです。
var clonedItem = Context.Parent.AsNoTracking()
.Include(u => u.Child1)
.Include(u => u.Child2)
// deep includes might go here (see ThenInclude)
.FirstOrDefault(u => u.ParentId == parentId);
// remove old id from parent
clonedItem.ParentId = 0;
// remove old ids from children
clonedItem.Parent1.ForEach(x =>
{
x.Child1Id = 0;
x.ParentId= 0;
});
clonedItem.Parent2.ForEach(x =>
{
x.Child2Id = 0;
x.ParentId= 0;
});
// customize entities before inserting it
// mark everything for insert
Context.Parent.Add(clonedItem);
// save everything in one single transaction
Context.SaveChanges();
もちろん、すべてを熱心にロードしたり、すべてのキーの値をリセットしたりするジェネリック関数を作成する方法はありますが、これにより、すべての手順が明確になり、カスタマイズ可能になります (たとえば、一部の子がまったく複製されないようにするには、含む)。
于 2019-02-04T08:23:28.767 に答える