2010-01-29 1 views
0

Обратите внимание, что это некоторая древняя установка NHibernate! У меня есть следующий NHibernate класс:NHibernate - конверсия не удалась при преобразовании даты и времени из двоичной/varbinary строки

[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(); 
} 

я получаю следующее исключение:

Конверсия удалось при преобразовании DateTime из двоичного/VARBINARY строка.

Так что я в основном предполагаю, что NHibernate еще не понял мой DateTime?. У моей установки NHibernate нет никакой фантазии Nullables.NHibernate.NullableDateTimeType. Итак, у кого есть ключ к решению этой древней проблемы NHibernate?

ответ

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) 
    { 
    } 
} 
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); 
     } 
    } 
} 
+0

Я засунуть что-нибудь вместе после того, как все :-) –