Entity Framework:デタッチオブジェクトとアタッチオブジェクトの操作

c# entity-framework

質問

まず、やりたいことを説明しましょう。 3種類のEntityObjectMetaDataData1 、およびData2ます。 MetaDataは、予想通り、 Data1Data2それぞれ1つのインスタンスへの参照を持ちます。これで、各MetaDataについて、 valueを計算できvalue

これまでのところとても単純です。それでは、ユーザーにData1Data2さまざまな組み合わせをData1もらい、それらがどのようなvalueを得られるのかを確認してください。これは明らかにMetaDataのインスタンスの作成を必要とします。さて、これらのMetaDataエントリすべてでデータベースを整理したくない場合は、 SaveChanges()を呼び出さずにエンティティオブジェクトをメモリ内のコンテキストで作成し、それをDBに書き戻します。ただし、これにより、メモリ内のMetaDataData1およびData2参照にアクセスしようとするたびに、次の例外が発生します。

InvalidOperationExceptionが未処理です

このEntityCollectionまたはEntityReferenceのソースクエリは、関連オブジェクトが追加状態またはデタッチ状態のいずれかにあり、NoTrackingマージオプションを使用してもともと取得されていない場合は返されません。

私が提案したようにしてオブジェクトをDBに「コミット」すると、混乱の問題になります。

とにかく、有罪コードは次のようになります。

MetaData temp = MetaData.CreateMetaData(0);

MetaData.Data1 = <existing Data1 from context>;
MetaData.Data2 = <existing Data2 from context>;

//Exception here
if (!MetaData.Data1Reference.isLoaded)
    MetaData.Data1Reference.Load();

この男も同様の問題を抱えていたようです。

受け入れられた回答

IsLoadedは、データベースから実体化されたインスタンスのプロパティにのみ関係します。あなたが発見したように、それはデータベースから具体化されていないインスタンスのために有用な情報を返しません。

したがって、Load()を呼び出すかどうかをテストする方法を変更する必要があります。あなたが、あなたがメモリ上で作成しただけでデータベースから具体化されていないMetaDataのインスタンスを使って作業することを知っているなら、あなたはこのようなコードを書くことができます:

if ((temp.EntityState != System.Data.EntityState.Added) && 
    (!temp.Data1Reference.IsLoaded)) temp.Data1Reference.Load();

私はここで、いくつかの微妙な点について説明しています。初心者にとって、EntityStateはFlagsAttributeで宣言されているので、Added と等しくなくてもAddedを含めることができます 。また、Data1Referenceがnull以外の場合、これは必要ありません。したがって、最初にそれをテストすることをお勧めします。ポイントは、あなたがあなたの状況に合ったコードを書くことができるということです、しかしそれはその性質だけではなく、臨時雇用者の完全な状態を説明しなければなりません。



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ