如何在不使用IUserType的情况下查询数据库时防止NHibernate SqlDateTime溢出?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在不使用IUserType的情况下查询数据库时防止NHibernate SqlDateTime溢出?相关的知识,希望对你有一定的参考价值。

在执行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.

我想将日期设置为支持的最小日期值。在插入和更新数据库时,我已经使用Interceptor执行此操作,但我正在寻找解决方案来修复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;
                    }
                }
            }
        }
    }
答案

不使用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):

  • Date NHibernate类型将不再被低于其基值(即1753年)的空值替换。它的基值现在是DateTime.MinValue。其配置参数已过时。

以上是关于如何在不使用IUserType的情况下查询数据库时防止NHibernate SqlDateTime溢出?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用窗口函数的情况下在大查询中选择 max(date)?

如何在不使用 join 或 cte 的情况下在同一查询中使用动态生成的列

如何在不重新加载的情况下修改 URL 查询字符串

如何在不使用 %s 的情况下安全、动态地在查询中设置列名?

如何在不保存 MS 访问查询的情况下将查询数据导出到 txt 文件

如何在不使用查询缓存的情况下缓存 Spring Data JPA 查询方法的结果?