Nhibernate中enum属性映射问题
在很早之前我写过《NHibernate中Mapping文件映射enum字段》
其中介绍了enum字段映射方法。但是最近发现了另一个问题。
问题描述
从昨晚开始一直在调试一个bug,不知道什么原因我的User实体只要获取实例,就有update语句产生,如果事务不commit看不出来,但是如果一次请求中有其他需要commit的时候,通过跟踪就会发现User也update了!莫名其妙啊。
public class User : IUser
{
/// <summary>
/// 版本控制
/// </summary>
public virtual int Version { get; set; }
/// <summary>
/// 用户账号
/// </summary>
public virtual string Account { get; set; }
/// <summary>
/// 用户密码
/// </summary>
public virtual string Password { get; set; }
/// <summary>
/// 用户状态
/// </summary>
public virtual UserStatus UserStatus { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public virtual DateTime CreateDate { get; set; }
/// <summary>
/// 登录次数
/// </summary>
public virtual int LoginTimes { get; set; }
}
/// <summary>
/// 用户状态
/// </summary>
public enum UserStatus
{
/// <summary>
/// 待定的
/// </summary>
Pending,
/// <summary>
/// 经批准的
/// </summary>
Approved,
/// <summary>
/// 被禁止的
/// </summary>
Forbidden
}
映射文件如下:
<class name="dotNet.Membership.User,dotNet.Membership" table="S_User" dynamic-update="true" >
<id name="Account" column="Account" type="string" length="50" unsaved-value="0" >
<generator class="assigned"></generator>
</id>
<version name="Version" column="ver" type="integer" unsaved-value="0"/>
<property name="Password" column="Password" type="string" length="50" not-null="true"></property>
<property name="CreateDate" column="CreateDate" type="DateTime" not-null="true" ></property>
<property name="UserStatus" column="UserStatus" type="Int32" not-null="true" ></property>
<property name="LoginTimes" column="LoginTimes" type="Int32" ></property>
</class>
这样每次获取User的时候都会产生Update语句只要在同一个事务中提交的话,就会更改User。
这造成了只要获取一次这个用户,那就版本号增加1。
解决方法
刚开始还以为业务代码在什么地方追加了这个user的更新,找来找去也没找到,那就更加莫名其妙了。慢慢的开始怀疑Nhibernate了。经过一天的努力查找,终于找到了原因。就是在配置enum属性对应的映射字段的时候,指定了type=”Int32”导致的。去掉这个设置问题消失。
Nhibernate默认可以根据实体的属性类型自动对应数据库的字段类型。如果你感觉有必要区分的才去设置这个type。例如:如果属性为string类型,那么SQLServer数据库中对应这个string的有char、varchar、Nchar、Nvarchar、text等等。如果你想使用text字段,那么需要在映射中制定type=”StringClob”。
<property name="Brief" column="brief" type="StringClob" />
在这里做一下备注,也提醒各位注意这个坑。也算不枉费我这一天多点的时间浪费!