我们在项目中会使用DTO作为数据业务领域模型来传输,在更新的时候会考虑并发问题,这里我只说下乐观并发控制。
首先我们在数据库表中增加一个 Timestamp类型的列 TS 作为版本控制
我使用的是CodeFirst方式,通过EF Power Tools 生成Model实体(具体生成方法可以百度一下),在Mapping类里我们可以看到EF 自动把这个TS列作为了 RowVersion
this.Property(t => t.TS)
.IsFixedLength()
.HasMaxLength(8)
.IsRowVersion();
有了这个属性,我们在更新的时候EF 会自动生成一个where 条件, where 主键='xxxx' and TS = 'xxxxxxxxxxxxx' 的条件
然后重点来了,我们把DTO传给WCF服务,通过主键获取到实体,然后用Automapper 将更新对象映射到原实体上,进行Attatch, 最后调用SaveChange,如果并发操作,我们会得到一个 DbUpdateConcurrencyException 并发操作异常。关键代码如下
业务层的更新方法
public void EditItem(DTO.DTO_EDIT_ITEM item)
{
ITEM oraItem = curdItem.GetByID(item.ITEM_GID);
oraItem = AutoMapper.Map<DTO_EDIT_ITEM, ITEM>(item, oraItem);
curdItem.Update(oraItem);
unitofWork.Commit();
}
Curd的Update方法
public virtual void Update(T entity)
{
context.Set<T>().Attach(entity);
context.Entry(entity).State = System.Data.EntityState.Modified;
}
public void Commit()
{
try
{
DataContext.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
//并发处理控制,捕获并发异常信息,以业务异常抛出
throw new BusinessException("数据已经被更改,请重新加载操作");
}
}