SQLite 与从数据库检索的 C# DateTime 不匹配

发布于 2024-10-22 19:16:36 字数 3099 浏览 0 评论 0原文

我正在尝试使用内存中的 SQLite 对我的应用程序运行一些单元测试,但我遇到了一个奇怪的问题:

我有两个查询。第一个查询的结果是给定列表名称的最新价格列表的日期,并且在第二个查询中使用 DateTime 来获取最新价格。问题是,第二个查询没有返回结果。

知道这里的背景可能出了什么问题吗?

        var effective = DbSession.Current.CreateCriteria<ItemPrice>()
                .SetProjection(Projections.Max("Effective"))
                .Add(Restrictions.Le("Effective", workDate))
                .CreateCriteria("PriceList")
                .Add(Restrictions.Eq("ListName", listName))
                .Add(Restrictions.Eq("Active", true))
                .UniqueResult<DateTime>();

        return DbSession.Current.CreateCriteria<ItemPrice>()
            .Add(Restrictions.Eq("Effective", effective))
            .CreateCriteria("PriceList")
            .Add(Restrictions.Eq("ListName", listName))
            .Add(Restrictions.Eq("Active", true))
            .List<ItemPrice>();

结果:最终实现了自定义 IUserType 将 DateTime 存储为字符串,并为 DateTime 添加了 Fluent Automapping 约定以使用它(如下所示):

class SQLiteDateTime : IUserType
    {
        #region IUserType Members

        public object Assemble(object cached, object owner)
        {
            return cached;
        }

        public object DeepCopy(object value)
        {
            var dt = (DateTime) value;
            return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
        }

        public object Disassemble(object value)
        {
            return String.Format("{0:yyyy'-'MM'-'dd' 'HH':'mm':'ss.fff}", value);
        }

        public new bool Equals(object x, object y)
        {
            return x.Equals(y);
        }

        public int GetHashCode(object x)
        {
            return x.GetHashCode();
        }

        public bool IsMutable
        {
            get { return false; }
        }

        public object NullSafeGet(IDataReader rs, string[] names, object owner)
        { 
            string dateString = (string)NHibernateUtil.String.NullSafeGet(rs, names[0]);
            DateTime result = DateTime.ParseExact(dateString, "yyyy'-'MM'-'dd' 'HH':'mm':'ss.fff", CultureInfo.InvariantCulture.DateTimeFormat);

            return result;
        }

        public void NullSafeSet(IDbCommand cmd, object value, int index)
        {  
            if (value == null)
            {
                NHibernateUtil.String.NullSafeSet(cmd, null, index);
                return;
            }
            value = Disassemble(value);
            NHibernateUtil.String.NullSafeSet(cmd, value, index);
        }  

        public object Replace(object original, object target, object owner)
        {
            return original;
        }

        public Type ReturnedType
        {
            get { return typeof (DateTime); }
        }

        public NHibernate.SqlTypes.SqlType[] SqlTypes
        {
            get {   
            var types = new SqlType[1];  
            types[0] = new SqlType(DbType.String);  
            return types;  
            } 
        }

        #endregion
    }

I'm attempting to run some unit tests on my application using SQLite in memory, but I've run into an odd problem:

I have two queries. The result of the first is the date of the most recent price list for a given list name, and that DateTime is used in the second query in order to fetch the most recent prices. The problem is, the second query returns no results.

Any idea what might be going wrong in the background here?

        var effective = DbSession.Current.CreateCriteria<ItemPrice>()
                .SetProjection(Projections.Max("Effective"))
                .Add(Restrictions.Le("Effective", workDate))
                .CreateCriteria("PriceList")
                .Add(Restrictions.Eq("ListName", listName))
                .Add(Restrictions.Eq("Active", true))
                .UniqueResult<DateTime>();

        return DbSession.Current.CreateCriteria<ItemPrice>()
            .Add(Restrictions.Eq("Effective", effective))
            .CreateCriteria("PriceList")
            .Add(Restrictions.Eq("ListName", listName))
            .Add(Restrictions.Eq("Active", true))
            .List<ItemPrice>();

Result: Ended up implementing a custom IUserType to store the DateTime as a string, and adding a Fluent Automapping convention for DateTime to use it (included below):

class SQLiteDateTime : IUserType
    {
        #region IUserType Members

        public object Assemble(object cached, object owner)
        {
            return cached;
        }

        public object DeepCopy(object value)
        {
            var dt = (DateTime) value;
            return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
        }

        public object Disassemble(object value)
        {
            return String.Format("{0:yyyy'-'MM'-'dd' 'HH':'mm':'ss.fff}", value);
        }

        public new bool Equals(object x, object y)
        {
            return x.Equals(y);
        }

        public int GetHashCode(object x)
        {
            return x.GetHashCode();
        }

        public bool IsMutable
        {
            get { return false; }
        }

        public object NullSafeGet(IDataReader rs, string[] names, object owner)
        { 
            string dateString = (string)NHibernateUtil.String.NullSafeGet(rs, names[0]);
            DateTime result = DateTime.ParseExact(dateString, "yyyy'-'MM'-'dd' 'HH':'mm':'ss.fff", CultureInfo.InvariantCulture.DateTimeFormat);

            return result;
        }

        public void NullSafeSet(IDbCommand cmd, object value, int index)
        {  
            if (value == null)
            {
                NHibernateUtil.String.NullSafeSet(cmd, null, index);
                return;
            }
            value = Disassemble(value);
            NHibernateUtil.String.NullSafeSet(cmd, value, index);
        }  

        public object Replace(object original, object target, object owner)
        {
            return original;
        }

        public Type ReturnedType
        {
            get { return typeof (DateTime); }
        }

        public NHibernate.SqlTypes.SqlType[] SqlTypes
        {
            get {   
            var types = new SqlType[1];  
            types[0] = new SqlType(DbType.String);  
            return types;  
            } 
        }

        #endregion
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷月断魂刀 2024-10-29 19:16:36

尝试为该列设置 Timestamp 的 CustomType。我认为这就是节省毫秒与不节省毫秒之间的区别。

Try setting a CustomType of Timestamp for that column. It's the difference between saving the milliseconds or not, I think.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文