当一个用户更新另一个用户已更新的entery时,我该如何解决模拟更新?
第一个用户请求'Category'entityobject,第二个用户也这样做 第二个用户更新此对象和第一个用户更新。
我在数据库中有字段时间戳字段,设置为并发模式 - 已修复。
这是我更新的方式:
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 :(得分:1)
您确定按照描述执行了一系列调用吗?无论如何,这里的主要问题是你不应该在Upate方法中使用查询返回的时间戳。您应该使用用户获取初始数据进行更新时收到的时间戳。它应该是:
原因是它可以在第一次调用和更新方法调用之间传递大量时间,因此可能已经处理了多个更改。您必须使用初始时间戳来避免静默覆盖其他更改。
编辑:
// 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)
{
...
}
}