1

あるユーザーが別のユーザーによってすでに更新されたEnteryを更新する場合、シミュレーションの更新をどのように解決すればよいですか?

最初のユーザーが「Category」entityobjectをリクエストし、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(.....);
}

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

4

1 に答える 1

1

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

  • ユーザーは更新からデータを要求します - すべてのフィールドとタイムスタンプは DB から受信されます
  • タイムスタンプはクライアントに保存されます (Web アプリの隠しフィールド)
  • ユーザーがデータを変更して保存ボタンを押す - 古いタイムスタンプを含むすべてのデータが処理に送信されます
  • Update メソッドは現在のエンティティを読み込みます
  • 更新されたすべてのフィールドは、古いエンティティとマージされます。エンティティのタイムスタンプは、最初のステップで受け取ったタイムスタンプに設定されます。
  • SaveChanges が呼び出されます

この理由は、最初の呼び出しと更新メソッドの呼び出しの間に多くの時間がかかる可能性があるため、すでにいくつかの変更が処理されている可能性があるためです。他の変更をサイレントに上書きしないようにするには、初期タイムスタンプを使用する必要があります。

編集:

// 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)     
    {               
        ...
    }     
} 
于 2011-01-15T13:13:02.283 に答える