【发布时间】:2013-04-12 10:21:29
【问题描述】:
我正在使用版本字段来控制 ASP.NET MVC 4 应用程序中的并发性。
映射:
<class name="User" table="Users">
<id name="Id">
<generator class="native"/>
</id>
<version name="Version" column="Version"/>
... other fields omitted for brevity...
实体:
public class User
{
public virtual int Id { get; set; }
public virtual int Version { get; set; }
... other fields omitted for brevity...
我正在使用以下方法:
- 按 Id 读取实体并映射到我的 UserDto 实体(Dto 用于数据传输对象模式),还包括版本字段
- 显示用于编辑 UserDto 实体的表单
- 接收 POSTed UserDto 实体
然后我执行以下操作:
// read the original entity from the database using my repository wrapper around NHibernate
var rep = RepositoryFactory.Create<User>(currentUnitOfWork);
User originalEntity = rep.GetById(userDto.Id);
// optimistic lock control - keep the version as the user saw it
originalEntity.Version = userDto.Version;
... other fields omitted for brevity...
rep.Update(originalEntity);
问题在于,即使 userDto.Version 与 originalEntity.Version 不匹配,NHibernate 也会忽略我的 userDto.Version 并使用 originalEntity.Version(显然,来自一级缓存,因为刚刚读取了实体)。 这种行为使我的版本字段完全无用。
如何强制 NHibernate 使用我提供的版本值而不是缓存的值?
此外,以某种方式使版本控制对使用我的存储库的其他程序员更加透明会很棒,但目前我不知道如何让它自动从接收到的实体中获取版本并强制 NHibernate 使用它甚至没有程序员注意到它。
有什么想法吗?
【问题讨论】:
-
您确定您的映射文件配置正确吗?它应该生成像
UPDATE People SET ... WHERE PersonID = @p0 AND Version = @p1这样的更新语句,其中@p1= 用户最初读取的版本。见Ayendes post on NHibernate Concurrency -
是的,它确实会生成,但 Version 的值是它刚刚从数据库中读取的值,而不是我在 originalEntity.Version = userDto.Version 中手动设置的值。看来,NHibernate 只是忽略了我对 Version 字段的手动更新。如果我在更新行中断并更改数据库中的版本,那么我会得到 ObjectStaleStateException,正如预期的那样。
标签: c# nhibernate web-applications dto optimistic-concurrency