在不使用 IUserType 查询数据库时如何防止 NHibernate SqlDateTime 溢出?
How to prevent NHibernate SqlDateTime overflow when querying the database without using an IUserType?
是否可以在执行如下所示的 NHibernate Linq 查询时防止此异常:
var dateFilter = DateTime.Parse("1500-01-01");
return _session.Query<Log>().Where(l => l.Date > dateFilter).ToList();
结果:
SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
我想将日期设置为支持的最小日期值。在插入和更新数据库时,我已经在使用拦截器来执行此操作,但我正在寻找修复 Select 查询的解决方案。
public class DataInterceptor : EmptyInterceptor
{
public override bool OnFlushDirty(object entity, object id, object[] currentState, object[] previousState, string[] propertyNames, IType[] types)
{
DateTimeMinValueToNull(currentState, types);
return base.OnFlushDirty(entity, id, currentState, previousState, propertyNames, types);
}
public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, IType[] types)
{
DateTimeMinValueToNull(state, types);
return base.OnSave(entity, id, state, propertyNames, types);
}
// Prevents the application from crashing when an object's DateTime value is lower than the SQL datetime min value
private void DateTimeMinValueToNull(object[] state, IType[] types)
{
for (int i = 0; i < types.Length; i++)
{
if (types[i].ReturnedClass == typeof(DateTime))
{
var value = (DateTime?)state[i];
if (value.HasValue && value.Value < (DateTime)SqlDateTime.MinValue)
{
state[i] = (DateTime)SqlDateTime.MinValue;
}
}
}
}
}
without using an IUserType
此限制是否只是为了避免更改您的映射?
与 NHibernate 5.2 一样,您可以将自定义类型注册为所有 DateTime
属性的默认类型:
//Somewhere before SessionFactory is created
TypeFactory.RegisterType(typeof(DateTime), new YourCustomDateTime(), new[] {"DateTime"});
使用此解决方案,您不需要当前的拦截器。
您使用的是哪个 NHibernate 版本?
在 5.0.0 版中,此行为发生了重大变化 (https://github.com/nhibernate/nhibernate-core/blob/5.1.5/releasenotes.txt):
- The Date NHibernate type will no more replace by null values below its base value (which was year 1753). Its base value is now
DateTime.MinValue. Its configuration parameter is obsolete.
是否可以在执行如下所示的 NHibernate Linq 查询时防止此异常:
var dateFilter = DateTime.Parse("1500-01-01");
return _session.Query<Log>().Where(l => l.Date > dateFilter).ToList();
结果:
SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
我想将日期设置为支持的最小日期值。在插入和更新数据库时,我已经在使用拦截器来执行此操作,但我正在寻找修复 Select 查询的解决方案。
public class DataInterceptor : EmptyInterceptor
{
public override bool OnFlushDirty(object entity, object id, object[] currentState, object[] previousState, string[] propertyNames, IType[] types)
{
DateTimeMinValueToNull(currentState, types);
return base.OnFlushDirty(entity, id, currentState, previousState, propertyNames, types);
}
public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, IType[] types)
{
DateTimeMinValueToNull(state, types);
return base.OnSave(entity, id, state, propertyNames, types);
}
// Prevents the application from crashing when an object's DateTime value is lower than the SQL datetime min value
private void DateTimeMinValueToNull(object[] state, IType[] types)
{
for (int i = 0; i < types.Length; i++)
{
if (types[i].ReturnedClass == typeof(DateTime))
{
var value = (DateTime?)state[i];
if (value.HasValue && value.Value < (DateTime)SqlDateTime.MinValue)
{
state[i] = (DateTime)SqlDateTime.MinValue;
}
}
}
}
}
without using an IUserType
此限制是否只是为了避免更改您的映射?
与 NHibernate 5.2 一样,您可以将自定义类型注册为所有 DateTime
属性的默认类型:
//Somewhere before SessionFactory is created
TypeFactory.RegisterType(typeof(DateTime), new YourCustomDateTime(), new[] {"DateTime"});
使用此解决方案,您不需要当前的拦截器。
您使用的是哪个 NHibernate 版本?
在 5.0.0 版中,此行为发生了重大变化 (https://github.com/nhibernate/nhibernate-core/blob/5.1.5/releasenotes.txt):
- The Date NHibernate type will no more replace by null values below its base value (which was year 1753). Its base value is now DateTime.MinValue. Its configuration parameter is obsolete.