[Serializable]
[Class(Table = "SomeEvents")]
public class SomeEvent
{
[Property(Column="processDate")]
public DateTime? ProcessDate { get; set; }
}
尝试更新某些事件时:
using (ISession session = FDK_Hibernate_Manager.OpenSession())
{
IQuery query = session.CreateQuery(string.Format("FROM {0} e WHERE e.ContractId = :cid", typeof(ContractLeverconditiesEvent)));
query.SetInt32("cid", contractId);
foreach(var evnt in query.List().Cast<SomeEvent>())
{
evnt.ProcessDate = DateTime.Now;
session.SaveOrUpdate(evnt);
}
session.Flush();
}
我收到以下例外:
从binary / varbinary字符串转换datetime时转换失败。
所以我基本上猜测NHibernate还不了解我的DateTime?
。我的NHibernate安装没有任何花哨的Nullables.NHibernate.NullableDateTimeType
。所以任何人都有解决这个古老的NHibernate问题的线索吗?
答案 0 :(得分:1)
我最终得到了这个(尽管它可能需要在错误检查方面做一些工作: - ))
使用[Property(Column = "processDate", TypeType = typeof(NullableDateTime))]
class NullableDateTime : IUserType
{
#region IUserType Members
public new bool Equals(object obj, object obj2)
{
return false;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public object DeepCopy(object value)
{
return value;
}
public bool IsMutable
{
get { return true; }
}
public object NullSafeGet(System.Data.IDataReader rs, string[] names, object owner)
{
object o = rs[names[0]];
if (o == DBNull.Value) return new Nullable<DateTime>();
else
return new Nullable<DateTime>(((System.Data.SqlTypes.SqlDateTime)o).Value);
}
public void NullSafeSet(System.Data.IDbCommand cmd, object value, int index)
{
System.Data.Common.DbParameter parameter = (System.Data.Common.DbParameter)cmd.Parameters[index];
if (value == null)
{
parameter.Value = DBNull.Value;
return;
}
else
{
parameter.Value = new System.Data.SqlTypes.SqlDateTime((DateTime)value);
}
}
public Type ReturnedType
{
get { return this.GetType(); }
}
public NHibernate.SqlTypes.SqlType[] SqlTypes
{
get { return new NHibernate.SqlTypes.SqlType[] { new SqlDateTimeType() }; }
}
#endregion
}
public class SqlDateTimeType : NHibernate.SqlTypes.SqlType
{
public SqlDateTimeType() : base(System.Data.DbType.DateTime)
{
}
}
答案 1 :(得分:0)
不幸的是,您可能不得不使用代理值(幻数)作为空日期。 1/1/1900是一种常见的选择。如果您可以映射私有成员(我不使用属性),您可以通过公共属性控制值:
public class SomeEvent
{
private DateTime _processDate; // map this
public SomeEvent()
{
_processDate = new DateTime(1900, 1, 1);
}
public DateTime? ProcessDate
{
get
{
if (_processDate == new DateTime(1900, 1, 1))
{
return null;
}
return _processDate;
}
set
{
_processDate = value ?? new DateTime(1900, 1, 1);
}
}
}