NHibernate Tips: 要注意模型与数据库在Null方面的匹配
先看一下说明代码,很简单,只为了说明情况
[ActiveRecord(Lazy=true)]
public class MyUser
{
private int _id;
[PrimaryKey(Generator=PrimaryKeyType.Identity)]
public virtual int Id
{
get { return _id; }
set { _id = value; }
}
private string _loginId;
[Property]
public virtual string LoginId
{
get { return _loginId; }
set { _loginId = value; }
}
private bool _isLock = false;
[Property(SqlType="int")]
public virtual bool IsLock
{
get { return _isLock; }
set { _isLock = value; }
}
private DateTime _createDate = DateTime.Now;
[Property]
public virtual DateTime CreateDate
{
get { return _createDate; }
set { _createDate = value; }
}
}
当使用如下代码时
string hql = " from MyUser ";
session.CreateQuery(hql).List(); // 第1次
session.CreateQuery(hql).List(); // 第2次
在第2次时,会报错:
SqlDateTime 溢出。必须介于 1/1/1753 12:00:00 AM 和 12/31/9999 11:59:59 PM 之间。
经调试发现(费时1个多小时,汗),结果发现只是因为数据库里CreateDate字段为空,导致该错误。将CreateDate字段设值后,不会报错了,但观察输出的sql语句,发现在第2次之前,NH产生了一个update语句,又经调试发现,是由于数据库中IsLock字段为空。将IsLock字段设值后,世界清静了。
总结
使用NHibernate时,要注意模型与数据库在Null方面的匹配。如果数据库允许为空,则模型的类型也应该是可为空的类型,比如应当使用DataTime?对应数据库中可为空的日期字段。.Net 1.1中没有可为空的DateTime类型,那只能在数据库中都设置为Not Null即可。
ps: 好象很多人都认为数据库设计中,最好不要让字段可为空。以前并不在意,但看来NH是坚定的执行了这一准则了
[ActiveRecord(Lazy=true)]
public class MyUser
{
private int _id;
[PrimaryKey(Generator=PrimaryKeyType.Identity)]
public virtual int Id
{
get { return _id; }
set { _id = value; }
}
private string _loginId;
[Property]
public virtual string LoginId
{
get { return _loginId; }
set { _loginId = value; }
}
private bool _isLock = false;
[Property(SqlType="int")]
public virtual bool IsLock
{
get { return _isLock; }
set { _isLock = value; }
}
private DateTime _createDate = DateTime.Now;
[Property]
public virtual DateTime CreateDate
{
get { return _createDate; }
set { _createDate = value; }
}
}
当使用如下代码时
string hql = " from MyUser ";
session.CreateQuery(hql).List(); // 第1次
session.CreateQuery(hql).List(); // 第2次
在第2次时,会报错:
SqlDateTime 溢出。必须介于 1/1/1753 12:00:00 AM 和 12/31/9999 11:59:59 PM 之间。
经调试发现(费时1个多小时,汗),结果发现只是因为数据库里CreateDate字段为空,导致该错误。将CreateDate字段设值后,不会报错了,但观察输出的sql语句,发现在第2次之前,NH产生了一个update语句,又经调试发现,是由于数据库中IsLock字段为空。将IsLock字段设值后,世界清静了。
总结
使用NHibernate时,要注意模型与数据库在Null方面的匹配。如果数据库允许为空,则模型的类型也应该是可为空的类型,比如应当使用DataTime?对应数据库中可为空的日期字段。.Net 1.1中没有可为空的DateTime类型,那只能在数据库中都设置为Not Null即可。
ps: 好象很多人都认为数据库设计中,最好不要让字段可为空。以前并不在意,但看来NH是坚定的执行了这一准则了