[解決済み] Entity Frameworkでオブジェクトが既にデータコンテキストにアタッチされているかどうかを確認することは可能ですか?
質問
あるコンテキストにすでにアタッチされているオブジェクトを、次のようなエラーでアタッチしようとします。
context.AttachTo(...)
:
同じキーを持つオブジェクトがすでにObjectStateManagerに存在しています。ObjectStateManagerは、同じキーを持つ複数のオブジェクトを追跡することはできません。
というようなことを実現する方法はないでしょうか。
context.IsAttachedTo(...)
乾杯
編集します。
Jasonが概説した拡張方法は近いのですが、私の状況ではうまくいきません。
私は別の質問に対する回答で概説された方法を使用して、いくつかの仕事をしようとしています。
Linq to Entitiesを使用して、最初に行を取得することなく、私のテーブルから1つまたは複数の行を削除するにはどうすればよいですか?
私のコードは少しこのようになります。
var user = new User() { Id = 1 };
context.AttachTo("Users", user);
comment.User = user;
context.SaveChanges();
これは問題なく動作しますが、そのユーザーに対して同じメソッドを使用してダミーの
User
オブジェクトをアタッチしようとしたときです。これは、私が以前にそのダミーユーザーオブジェクトを添付したため、失敗します。どのように私はこれをチェックすることができますか?
どのように解決するのですか?
最終的には以下のようになり、とてもうまくいきました。
public static void AttachToOrGet<T>(this ObjectContext context, string entitySetName, ref T entity)
where T : IEntityWithKey
{
ObjectStateEntry entry;
// Track whether we need to perform an attach
bool attach = false;
if (
context.ObjectStateManager.TryGetObjectStateEntry
(
context.CreateEntityKey(entitySetName, entity),
out entry
)
)
{
// Re-attach if necessary
attach = entry.State == EntityState.Detached;
// Get the discovered entity to the ref
entity = (T)entry.Entity;
}
else
{
// Attach for the first time
attach = true;
}
if (attach)
context.AttachTo(entitySetName, entity);
}
以下のように呼び出すことができます。
User user = new User() { Id = 1 };
II.AttachToOrGet<Users>("Users", ref user);
と同じなので、とてもうまく動作します。
context.AttachTo(...)
のように、毎回引用したIDのトリックを使うことができることを除けば、これはとてもうまくいきます。最終的には、以前アタッチされていたオブジェクトか、あなた自身のオブジェクトがアタッチされることになります。呼び出し
CreateEntityKey
を呼び出すことで、うまく汎用的になり、複合キーでもさらなるコーディングなしで動作するようになります(EFがすでにそれをやってくれているからです!)。
編集、12年後(2021年12月)...ウフフ!
EF Coreで使っているのはこんな感じです。
public static class EfExtensions
{
public static T AttachToOrGet<T>(this DbContext context, Func<T,bool> predicate, Func<T> factory)
where T : class, new()
{
var match = context.Set<T>().Local.FirstOrDefault(predicate);
if (match == null)
{
match = factory();
context.Attach(match);
}
return match;
}
}
使用方法
var item = db.AttachToOrGet(_ => _.Id == someId, () => new MyItem { Id = someId });
これをリファクタリングしてエンティティキーで動作させることもできますが、これだけでも十分です!
関連
-
[解決済み】WCFとは何か、何ができるのか?
-
[解決済み】この動詞型ではcontent-bodyを送信できない
-
[解決済み] 不変量名 'System.Data.SqlClient' を持つ ADO.NET プロバイダに対応する Entity Framework プロバイダが見つかりませんでした。
-
[解決済み] DelphiとDelphi.NETの違いについて
-
[解決済み] .net の OOM 問題を解決する必要があります。
-
[解決済み] Entity FrameworkとLINQ to SQLの比較
-
[解決済み] Entity Frameworkにおける最速の挿入方法
-
[解決済み] Entity Frameworkで生成されたSQLを表示するにはどうすればよいですか?
-
[解決済み] MemoryStreamから文字列を取得する方法は?
-
[解決済み] ASP.NET MVC - 'MODELNAME' 型のエンティティのアタッチに失敗しました。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] ポストバックまたはコールバックの引数が無効です。 イベント検証は '<pages enableEventValidation="true"/>' を使用して有効になっています。
-
[解決済み] "ItemsSourceを使用する前に、Itemsコレクションを空にする必要があります。"
-
[解決済み] C++/CLIにおけるキャレット('^')の意味は?
-
[解決済み] EF Coreのadd-migrationのビルドに失敗しました。
-
[解決済み] 24:00:00 を超える値を持つ .Net Timespan を格納するための正しい SQL タイプは何ですか?
-
[解決済み] 'Newtonsoft.Json' には 'Microsoft.CSharp' の依存関係がすでに定義されています。
-
[解決済み] ファイルまたはアセンブリをロードできませんでした 操作がサポートされていません。(HRESULT: 0x80131515 からの例外)
-
[解決済み] Powershell v3 Invoke-WebRequest HTTPSエラー
-
[解決済み] 列挙型を文字列に変換する
-
[解決済み] HashSetとListの性能比較