2016-08-18 11 views
1

それはこのように書きます:奇妙な行動は

MyDbContext ctx = new MyDbContext(); 

IFooRepository repo = new FooRepository(ctx); 
var items = repo.GetAvailableItem().ToList(); //this will query all item.sold = false. 

// here it returns three rows 
foreach(var item in items) { 
    item.sold = true; 
} 

repo.commit();  // this will call the SaveChanges() in DbContext 

Thread.sleep(10000) 

// Now I quickly execute a query in SQL Server Management Studio 
// UPDATE Item SET Sold = 0; 
var items02 = repo.GetAvailableItem().ToList(); // this will query all item.sold = false. 

// here items02 also contains three rows 
// HOWEVER, when I watch the value of item.sold in items02, it is all True 

これは仕様による動作ですか?

なぜですか?それはDbContextがエンティティをキャッシュし、同じクエリを再度実行しても更新されないためですか?ここで


UPDATE

私のレポのコードです:

public IQueryable<Item> GetAvailableItem() 
{ 
    var items = from x in DbContext.Item 
         where x.Sold == 0 
         select x; 
    return items; 
} 

public virtual int Commit() 
{ 
    return DbContext.SaveChanges(); 
} 
+3

があなたの 'GetAvailableItemを()'ポストと '()'メソッドをコミットしてくださいを参照してください。何かが間違っていると思われる –

答えて

4

OK。これは起こっていることです:

  1. 新しいコンテキストを作成しています。
  2. dbからアイテムをロードするときは、GetAvailableItem()
  3. Contextがロードしてキャッシュします。
  4. コンテキストを使用してアイテムを更新しています。したがって、db行は更新され、キャッシュされたバージョンも更新されます。
  5. (SSMSを使用して)コンテキスト外でpure SQLを使用してアイテムを更新しています。そう:db行は更新されます。しかし、以前と同じコンテキストを使用しているので、それ自身のバージョンのアイテムがあり、自分自身の外で何が起こっているのかを知る方法がないので、キャッシュされたアイテムのバージョンはそのままです: 。

コンテキスト内に変更があることを知りたい場合は、新しいコンテキストを作成して再度クエリするのが最も簡単な方法です。もう1つの方法は、yourContext.Entry<YourEntityType>(entityInstance).Reload();によってdbからエンティティを再読み込みするために文脈を明示することです。

+0

良い説明。今私はそれがどのように機能するのか理解していますエティエンヌは何かを非常に重要なものとしても述べている。 dbContextを操作するときの正しい習慣は、可能な限り短くしておくことです。 – Terrence

+0

Ur wlcm。また、次のことを覚えておいてください。1. 'IQueryable'をリポジトリから返すのは良い習慣ではありません。 'DbContext'はリポジトリそのものですが、リポジトリパターンを使うのは良い方法ではありません。 –

+0

ああ、私はすべてIListを返すように変更するつもりです。ありがとう – Terrence

1

私の推測では、DbContextは、データベースで行われた変更(最新のものはThread.sleepの間に更新されていると言われています)には最新のものではありません。 DbContextはこれらの更新を取得しません(データはキャッシュされます)。

これは、コンテキストのライフスコープをできるだけ短くして並行性を低下させたいからです。これは予想される動作です。

このMSDN post