날짜가 9999-21-31, 인 날짜를 저장하는 레거시 DB가 있습니다. Till_Date
열은 DateTime not-null="true"
입니다.NHibernate IUserType nullable DateTime을 DB가 아닌 값으로 변환합니다.
응용 프로그램에서 null이 아닌 날짜를 나타내는 지속 된 클래스를 작성하려고합니다. 그래서 C# // public DateTime에 Nullable DateTime을 사용 했습니까? TillDate {get; 세트; }
나는 9999-12-31을 dB로 엔티티 널 (null) 값을 변환 할 알고 있지만 엔티티 값이 null 인 경우 NHibernate에 내 IUserType 에 SafeNullGet, SafeNullSet를 호출하지 않는 것 같다 IUserType을 만들어
, null이 아닌 열에 null이 사용되었다고보고합니다.
나는 NULL이 아닌 "false" (DB가 아닌 매핑 파일 만 변경됨) 으로 열을 매핑하여 우회하려고했으나 여전히 도움이되지 않으며 삽입 만 시도합니다 DB 에의 null 치를 취득 해, ADOException를 취득합니다.
NHibernate가 널 값이 아닌 값으로 변환하는 IUseType을 지원하지 않는다면 어떤 지식이 있습니까?
// 구현하기 전에 필요한 수정 사항 !!! 수정과
public class NullableDateTimeToNotNullUserType : IUserType
{
private static readonly DateTime MaxDate = new DateTime(9999, 12, 31);
public new bool Equals(object x, object y)
{ //This didn't work as well
if (ReferenceEquals(x, y)) return true; //if(x == null && y == null) return false;
if (x == null || y == null) return false;
return x.Equals(y);
}
public int GetHashCode(object x)
{
return x == null ? 0 : x.GetHashCode();
}
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
var value = rs.GetDateTime(rs.GetOrdinal(names[0]));
return (value == MaxDate)? null : value;
}
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
var dateValue = (DateTime?)value;
var dbValue = (dateValue.HasValue) ? dateValue.Value : MaxDate;
((IDataParameter)cmd.Parameters[index]).Value = dbValue;
}
public object DeepCopy(object value)
{
return value;
}
public object Replace(object original, object target, object owner)
{
return original;
}
public object Assemble(object cached, object owner)
{
return cached;
}
public object Disassemble(object value)
{
return value;
}
public SqlType[] SqlTypes
{
get { return new[] { NHibernateUtil.DateTime.SqlType }; }
}
public Type ReturnedType
{
get { return typeof(DateTime?); }
}
public bool IsMutable
{
get { return false; }
}
}
}
는 // 최종 구현.
//Make the column mapping in hbm.xml not-null="false" even if in DB null not allowed.
//Make sure the class mapping in xml doesn't have dynamic-insert="true"
public class NullableDateTimeToNotNullUserType : IUserType
{
private static readonly DateTime MaxDate = new DateTime(9999, 12, 31);
public new bool Equals(object x, object y)
{ //This didn't work as well
if (ReferenceEquals(x, y)) return true; //if(x == null && y == null) return false;
if (x == null || y == null) return false;
return x.Equals(y);
}
public int GetHashCode(object x)
{
return x == null ? 0 : x.GetHashCode();
}
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
var value = NHibernateUtil.Date.NullSafeGet(rs, names[0]);
return (value == MaxDate)? default(DateTime?) : value;
}
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
var dateValue = (DateTime?)value;
var dbValue = (dateValue.HasValue) ? dateValue.Value : MaxDate;
NHibernateUtil.Date.NullSafeSet(cmd, valueToSet, index);
}
public object DeepCopy(object value)
{
return value;
}
public object Replace(object original, object target, object owner)
{
return original;
}
public object Assemble(object cached, object owner)
{
return cached;
}
public object Disassemble(object value)
{
return value;
}
public SqlType[] SqlTypes
{
get { return new[] { NHibernateUtil.DateTime.SqlType }; }
}
public Type ReturnedType
{
get { return typeof(DateTime?); }
}
public bool IsMutable
{
get { return false; }
}
}
}
디버깅을 사용하면 비교 된 값 모두에 대해 equals에 대한 호출이 null을 전달한다는 것을 알 수 있습니다. 는 그에 대해 같음 2 버전을 시도 : 비교 값이 비교 값이 null의 경우는 null 2 반환 거짓 경우는 true 1 수익을 난 당신의 코드에 따라 일을 조정 TNX – barakbbn
추가 코드 구현 (추가 명시 적 캐스팅을 참조하십시오 다음 시나리오를 제외하고 작동 날짜가 최대 (예 : 2010-01-01) 이 아니고 엔터티를 가져 와서 날짜를 null로 변경하고 변경 사항을 저장하면 그 다음 false를 반환하는 Equals (2010-01-01, null)를 호출하지만 NullSafeSet을 호출하지 않고 다음 예외를 throw합니다. NHibernate.PropertyVa lueException : not-null 프로퍼티가 null 또는 일시적인 값을 참조한다 그런 다음 매핑을 hbm.xml에서 not-null = "false"로 변경했으며이 시간에 NullSafeSet이 호출되었습니다. 도움을 주셔서 감사합니다. – barakbbn
null이 아닌 설정이이 작업에 영향을 미친다는 사실에 조금 놀랐습니다. 스키마 생성에만 해당되는 것으로 생각했습니다. 그것이 도움이된다면 답을 upvote하고 동의하십시오. –