77

Entity Framework 5 ( DBContext) を使用しており、エンティティをディープ コピー (つまり、エンティティとすべての関連オブジェクトをコピー) し、新しいエンティティをデータベースに保存する最良の方法を見つけようとしています。これどうやってするの?などの拡張メソッドの使用を検討しましCloneHelperたが、 に適用されるかどうかはわかりませんDBContext

4

4 に答える 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 に答える