2011-01-15 13 views
1

シミュレーション更新を解決する方法はありますか?Entity Frameworkのオプティミスティック同時実行性アップデートの問題を解決する

第1のユーザ要求「カテゴリ」エンティティオブジェクト、第2のユーザも同じことを行う。
2人目のユーザーがこのオブジェクトと最初のユーザーの更新を更新します。

私は同時実行モードに設定されたデータベースにフィールドタイムスタンプフィールドを持っています - 固定。

これは私が更新する方法です:

public class CategoriesRepository : BaseCategoryRepository 
{ 

    public void Update(....) 
    { 
    try 
    { 
      Category catToUpdate = (from c in Contentctx.Categories where c.CategoryID == categoryId select c).FirstOrDefault(); 
      catToUpdate.SectionReference.EntityKey = new System.Data.EntityKey("ContentModel.Sections", "SectionID", sectionId); 

      if (catToUpdate != null) 
      { 
       //Set fields here.... 
       Contentctx.SaveChanges(); 
      } 

      base.PurgeCacheItems(CacheKey); 
    } 

    catch (OptimisticConcurrencyException ex) 
    { 

      } 
    } 

} 
//Contentctx comes from base class: Contentctx: 
private ContentModel _contenttx; 
     public ContentModel Contentctx 
     { 
      get 
      { 
       if ((_contenttx == null)) 
       {     
        _contenttx = new ContentModel(); 
       } 

       return _contenttx; 
      } 
      set { _contenttx = value; } 
     } 



//on Business layer: 
using (CategoriesRepository categoriesRepository = new CategoriesRepository()) 
{ 
      categoriesRepository.UpdateCategory(.....); 
} 

例外がジャンプしたことがない...
はどのように私はこれを処理する必要がありますか?

+0

たぶんリンクはあなたを助けることができる。[方法:オブジェクトコンテキストでデータの同時実行を管理する](http://msdn.microsoft.com/en-us/library/vstudio/ bb399228(v = vs.100).aspx) – huoxudong125

答えて

1

説明したように一連の呼び出しが実行されていますか?とにかくここでの主な問題は、Upateメソッドでクエリから返されたタイムスタンプを使用しないでください。ユーザーが更新のための初期データを取得したときに受け取ったタイムスタンプを使用する必要があります。それは次のようになります。

  • ユーザーは、更新データを要求 - すべてのフィールドとタイムスタンプがDB
  • から受信されているタイムスタンプは、クライアント(ウェブアプリで隠しフィールド)に保存されている
  • ユーザーがデータを変更し、[保存]ボタンを押して - 古いタイムスタンプを含むすべてのデータがprocessinに送信されます
  • 更新メソッドは現在のエンティティをロードします
  • 更新されたすべてのフィールドは古いエンティティとマージされます。エンティティのタイムスタンプは、最初のステップで受信したタイムスタンプに設定されます。
  • SaveChangesメソッドは、この理由は、すでに処理いくつかの変更ができるように、それは最初の呼び出しとupdateメソッドの呼び出しの間に多くの時間を渡すことができるということです

と呼ばれています。サイレントで他の変更を上書きしないように、初期タイムスタンプを使用する必要があります。

編集:

// You are updating category - update probably means that you had to load category 
// first from database to show actual values. When you loaded the category it had some 
// timestamp value. If you don't use that value, any change between that load and c 
// calling this method will be silently overwritten. 
public void Update(Category category)  
{  
    try  
    {   
     Category catToUpdate = (from c in Contentctx.Categories where c.CategoryID == categoryId select c).FirstOrDefault();   
     ...   

     // Now categoryToUpdate contains actual timestamp. But it is timestamp of 
     // actual values loaded now. So if you use this timestamp to deal with 
     // concurrency, it will only fire exception if somebody modifies data 
     // before you call SaveChanges few lines of code bellow. 

     if (catToUpdate != null)   
     {     
      //Set fields here.... 

      // To ensure concurrency check from your initial load, you must 
      // use the initial timestamp.   
      catToUpdate.Timestamp = category.Timestamp; 
      Contentctx.SaveChanges();   
     } 

     ... 
    }  
    catch (OptimisticConcurrencyException ex)  
    {    
     ... 
    }  
} 
+0

クエリでタイムスタンプreturendを使用してはいけないとはどういう意味ですか?私はそれを使用していない... EFは自動的に処理する必要があります(同時性モード - 固定。)?私が保存したタイムスタンプで何をするのですか? – asker

+0

//ここでフィールドを設定しますか?タイムスタンプも設定しますか?修正されたタイムスタンプは、EFが更新SQL文の条件にタイムスタンプを追加することを意味します。 –

+0

いいえ!私はタイムスタンプを設定していません! – asker

関連する問題