1

エンティティフレームワーク4.1を使用し、asp.net mvcで最初にコードしています。ちょうど私が以下のコード(コントローラ)を書いたことをテストするために。あなたが見ることができる上記のコードでは、直接読み込み時と変数読み込み時に異なる値を示すエントリ状態

public ActionResult Foo() 
{ 
    StringBuilder sb = new StringBuilder(); 
      using (var db = new DemoDataBase1Context()) 
      { 
       //get person from db 
       var person = db.Persons.FirstOrDefault(); 

       //get entry 
       var entry = db.Entry(person); 

       //now change the person object 
       person.Name = "Some New Value"; 

       //print entity state 

       //this is showing unchanged 
       sb.Append("<br>State: " + entry.State); 

       //this is showing changed 
       sb.Append("<br>State: " + db.Entry(person).State);     
      } 

    return Content(sb.ToString()); 
} 

IAMは、私がしなければそのは、変わらないと言っentry.Stateをやっdb.Entry(person).Stateその格言が変更されました。どのような理由で説明できますか?

答えて

2

あなたは内部DetectChangesを呼び出しEntry(EF 4.1のデフォルト)有効な自動変化検出を使用している場合。この方法は、これにはおそらく同様の始まり:

db.Entry(person)のあなたの2回目の呼び出しで
if (Configuration.AutoDetectChangesEnabled) 
    ChangeTracker.DetectChanges(); 
//... 

オブジェクトが変更されたとDetectChanges方法では、現在の値を持つエンティティをロードしたときに作られたスナップショットを比較することによって、これを検出します。差異があるため、状態はUnchangedからModifiedに変わります。

またDbEntityEntry.Stateの可能性が高いだけで、両方のDbEntityEntryオブジェクト内の同じインスタンスままインナー_internalEntityEntryState値を伝播する性質であるため、変更はModifiedに行く前に、あなたが作成したentryオブジェクトのState

あなたは本当にあなたがState自体を保存する必要があるエンティティの以前の状態を保存したい場合は、だけでなく、entry対象:

var state = db.Entry(person).State; 

これは単なる列挙され、後に変更されることはありませんEntryに電話してください。

あなたが自動変更検出を無効にするときは、行動でこの動作を比較することができ

:EFはもう今あなたのPOCOの1つに気づかれていないため

db.Configuration.AutoDetectChangesEnabled = false; 

どちらsb.Append...行が、その場合には状態Unchangedを受け取ることになりますDetectChangesが呼び出されていないため、プロパティが変更されました。

1

Entryメソッドは、Entryを呼び出すときと同じようにオブジェクトの状態を提供します。私はそれが変数から直接それを呼び出すのとは何か関係がないとは思わない。

最初のエントリへの参照を取得すると、オブジェクトは変更されません。次の行でそれを変更し、Entryを再度呼び出すと、その時点で変更されます。あなたはそれへの参照を格納した場合、私は、彼らが異なる参照である推測しています2を比較:

var person = db.Persons.FirstOrDefault(); 

// get reference to entry - unchanged at this point 
var entry1 = db.Entry(person); 

// make a change to the object 
person.Name = "Changed"; 

// get reference to entry - changed now 
var entry2 = db.Entry(person); 

// these will not be equal: probably false 
var equalOrNot = entry1 == entry2; 
+0

私はちょうどチェックしました:この文の後に 'var entry2 = db.Entry(person);' | 'entry1.State'と' entry2.State'は両方ともModifiedです。今、私は 'var entry2 = db.Entry(person);'をコメントアウトしました.'、 'entry1.State'はModifiedを示しています。私はなぜそれが起こっているのか知りません。 –

+0

あなたの行動を示すコードを更新してください。私がテストを走らせたとき、それは期待通りに機能しました。 – Dismissile

関連する問題