エンティティフレームワーク5(DBContext
)を使用していますが、エンティティを深くコピーする(エンティティと関連するオブジェクトをすべてコピーする)ベストな方法を見つけようとしています。データベース内の新しいエンティティこれどうやってするの?私はCloneHelper
のような拡張方法を調べましたが、それがDBContext
に適用されるかどうかはわかりません。エンティティフレームワーク5エンティティのディープコピー/クローン
答えて
エンティティをクローニングの一つ安い簡単な方法は、このような何かを行うことです。
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);
このトリックはかなりの時間を私に安全に与えました:-)。しかし、私のDbContextの設定では、エンティティを自動的に追加できないという例外がありました。私はこの 'DirectControl(DbContext、IObjectContextAdapter).ObjectContext.AddObject(entitySetName、entity)'のようなObjectContextに行きます。 – Patrick
これは 'dbContext、Select(x => {a = x、ab = ToList() '' AsNoTracking() 'を追加すると、クエリからデータが消失します。x.MyCollection.Where(g => g.Id> 2)}) – Eldho
これはEFコアを使用して私にとって素晴らしい仕事をしました。しかし、EFがデータベースに重複行を挿入しようとするのを防ぐために、親とネストされたオブジェクトの主キーをGuid.Emptyに設定する必要がありました。整数キーを使用する場合、0に設定すると同じ効果があると思われます。 – agileMike
ここでは別のオプションがあります。
データを複製するためのクエリを特に実行する必要がないため、私はそれを好む場合があります。このメソッドを使用すると、すでにデータベースから取得したエンティティのクローンを作成できます。
//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();
このメソッドは、ソースからの現在の値を追加された新しい行にコピーします。
これは、クローンを1つのSaveChangesにオリジナルのアップデートと共に挿入したい場合に効果的です – Dacker
新しいオブジェクトが添付されていない場合、 'SetValues'は機能しません文脈'InvalidOperationException'例外がスローされます。エンティティをデタッチ状態で複製するだけの場合は、エンティティをコンテキストに追加し、現在の値を設定してからデタッチすることができます。 – Suncat2000
これは一般的なクローニングを可能にする一般的な拡張方法です。
ナゲットからSystem.Linq.Dynamic
を取得する必要があります。
public TEntity Clone<TEntity>(this DbContext context, TEntity entity) where TEntity : class
{
var keyName = GetKeyName<TEntity>();
var keyValue = context.Entry(entity).Property(keyName).CurrentValue;
var keyType = typeof(TEntity).GetProperty(keyName, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).PropertyType;
var dbSet = context.Set<TEntity>();
var newEntity = dbSet
.Where(keyName + " = @0", keyValue)
.AsNoTracking()
.Single();
context.Entry(newEntity).Property(keyName).CurrentValue = keyType.GetDefault();
context.Add(newEntity);
return newEntity;
}
自分で実装する必要があるのは、GetKeyNameメソッドだけです。これはからreturn the first guid property
までのいずれかであるか、DatabaseGenerated(DatabaseGeneratedOption.Identity)]
とマークされた最初のプロパティを返します。私の場合は
私はすでに、私は以下の[リンク](http://code.msdn.microsoftで説明リフレクションを使用してエンティティオブジェクトを複製/ディープクローンしようとした[DataServiceKeyAttribute("EntityId")]
private string GetKeyName<TEntity>() where TEntity : class
{
return ((DataServiceKeyAttribute)typeof(TEntity)
.GetCustomAttributes(typeof(DataServiceKeyAttribute), true).First())
.KeyNames.Single();
}
- 1. エンティティでのエンティティフレームワーク
- 2. エンティティへのエンティティフレームワークのlinq
- 3. エンティティフレームワーク5とXElementフィールド
- 4. エンティティフレームワーク自己参照エンティティ
- 5. エンティティフレームワーク:更新関連エンティティ
- 6. エンティティフレームワークCTP 5 - リポジトリパターン - 更新中
- 7. asp.net MVC 5エンティティフレームワーク - DropDownListForトリムスペース?
- 8. エンティティフレームワークでのエンティティの削除と挿入
- 9. ルーピングおよびエンティティフレームワークのエンティティのヘルプ
- 10. 共有エンティティとのエンティティフレームワークのマッピング
- 11. エンティティフレームワークの列とエンティティの相関?
- 12. エンティティフレームワークでの関連エンティティのフィルタリング
- 13. エンティティフレームワーク - エンティティの検証エラーがアズール
- 14. エンティティフレームワーク内のエンティティを更新する
- 15. エンティティフレームワーク:混合エンティティの混合述語
- 16. エンティティフレームワーク:エンティティAを既存のエンティティBにリンクする
- 17. エンティティフレームワーク - ビュー2切断エンティティ更新
- 18. エンティティフレームワーク追加エンティティで子エンティティも追加されます
- 19. Asp mvc 5エンティティのフレームワーク6
- 20. ASP .NET - MVC 5 - エンティティフレームワーク - コードファースト - フォーム認証
- 21. エンティティフレームワーク5コードファースト - 「やり直す」方法
- 22. エンティティフレームワーク1対1リレーションシップ依存エンティティなしの依存エンティティを保存する
- 23. エンティティフレームワーク:特定のタイプのすべてのエンティティを取得
- 24. エンティティフレームワーク:ネストされたエンティティにトップ・レベル・エンティティ与えられた条件を選択
- 25. エンティティフレームワークの自己追跡エンティティでの更新
- 26. エンティティフレームワーク(C#ASP.NET) - 非依存エンティティでのトラッキングのないアソシエーションエンティティ
- 27. エンティティフレームワーク:1対多の関係の共通エンティティ
- 28. 2つの異なるエンティティフレームワーク内の同じエンティティ名
- 29. エンティティフレームワーク、マッピングされていないエンティティでの作業方法
- 30. エンティティフレームワークの関連エンティティにインクルードするために使用する
で私のクラスをマーク。 com/CSEFDeepCloneObject-12a5cb95)しかし、私が理解しているように、EntityObjectの派生型はDbContext APIでサポートされていません – kypk