NHibernate - 从binary / varbinary字符串转换datetime时转换失败

时间:2010-01-29 14:03:52

标签: c# nhibernate

注意,这是一些古老的NHibernate安装!我有以下NHibernate类:

[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问题的线索吗?

2 个答案:

答案 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);
        }
    }
}