nhibernate - 将 TimeSpan 属性保存到时间类型 Mysql 列时出错

标签 nhibernate fluent-nhibernate

我有一个 TimeSpan 属性,我想使用 Nhibernate 将其保存到 DB。 Mysql 列类型是时间。我读过那个

CustomType("TimeAsTimeSpan")

应该可以解决问题,但事实并非如此。

session.Save(object)

将导致以下 MySqlException

Only TimeSpan objects can be serialized by MySqlTimeSpan Error

我试图保留的时间戳属性是一个有效的时间戳。有什么建议吗?

最佳答案

这是 NHibernate 中的一个错误。我刚刚通过创建 TimeAsTimeSpan 类的克隆解决了这个问题。

用法:

CustomType(typeof(TimeAsTimeSpanTypeClone));

类:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using NHibernate.Engine;
using NHibernate.SqlTypes;
using NHibernate.Type;

namespace DataAccess.NhibernateFixes
{
    /// <summary>
    /// Clone of the Nhibernate class: NHibernate.Type.TimeAsTimeSpanType
    /// This one actually works though...
    /// </summary>
    [Serializable]
    public class TimeAsTimeSpanTypeClone : PrimitiveType, IVersionType, IType, ICacheAssembler
    {
        private static readonly DateTime BaseDateValue = new DateTime(1753, 1, 1);

        public override string Name
        {
            get
            {
                return "TimeAsTimeSpan";
            }
        }

        public override System.Type ReturnedClass
        {
            get
            {
                return typeof(TimeSpan);
            }
        }

        public IComparer Comparator
        {
            get
            {
                return (IComparer)Comparer<TimeSpan>.Default;
            }
        }

        public override System.Type PrimitiveClass
        {
            get
            {
                return typeof(TimeSpan);
            }
        }

        public override object DefaultValue
        {
            get
            {
                return (object)TimeSpan.Zero;
            }
        }

        static TimeAsTimeSpanTypeClone()
        {
        }

        public TimeAsTimeSpanTypeClone()
            : base(SqlTypeFactory.Time)
        {
        }

        public override object Get(IDataReader rs, int index)
        {
            try
            {
                object obj = rs[index];
                if (obj is TimeSpan)
                    return (object)(TimeSpan)obj;
                else
                    return (object)((DateTime)obj).TimeOfDay;
            }
            catch (Exception ex)
            {
                throw new FormatException(string.Format("Input string '{0}' was not in the correct format.", rs[index]), ex);
            }
        }

        public override object Get(IDataReader rs, string name)
        {
            try
            {
                object obj = rs[name];
                if (obj is TimeSpan)
                    return (object)(TimeSpan)obj;
                else
                    return (object)((DateTime)obj).TimeOfDay;
            }
            catch (Exception ex)
            {
                throw new FormatException(string.Format("Input string '{0}' was not in the correct format.", rs[name]), ex);
            }
        }

        public override void Set(IDbCommand st, object value, int index)
        {
            DateTime dateTime = TimeAsTimeSpanTypeClone.BaseDateValue.AddTicks(((TimeSpan)value).Ticks);
            ((IDataParameter)st.Parameters[index]).Value = (object)dateTime.TimeOfDay; // <<<<  fix here. Added ".TimeOfDay"
        }

        public override string ToString(object val)
        {
            return ((TimeSpan)val).Ticks.ToString();
        }

        public object Next(object current, ISessionImplementor session)
        {
            return this.Seed(session);
        }

        public virtual object Seed(ISessionImplementor session)
        {
            return (object)new TimeSpan(DateTime.Now.Ticks);
        }

        public object StringToObject(string xml)
        {
            return (object)TimeSpan.Parse(xml);
        }

        public override object FromStringValue(string xml)
        {
            return (object)TimeSpan.Parse(xml);
        }

        public override string ObjectToSQLString(object value, NHibernate.Dialect.Dialect dialect)
        {
            return (string)(object)'\'' + (object)((TimeSpan)value).Ticks.ToString() + (string)(object)'\'';
        }
    }
}

关于nhibernate - 将 TimeSpan 属性保存到时间类型 Mysql 列时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11314426/

相关文章:

asp.net - 在 asp.net MVC2 中的每个 Web 请求上创建的 nhibernate session

c# - NHibernate 使用公共(public)属性映射到实体

asp.net-mvc - 在 Asp.Net MVC 应用程序中使用 Structuremap 将 ISession 注入(inject)我的存储库

nhibernate - FluentNHibernate,从另一个表中获取 1 列

NHibernate 使用错误的表别名

c# - 实体可以附加到以前未附加的 ISession 吗?

NHibernate 级联集合在将新项目插入非空集合时删除

c# - 如何让 NHibernate 通过我的函数将所有 sql 查询作为字符串转发?

c# - 在 NHibernate 中管理 session 的最佳方式?

configuration - 如何使用 Fluent NHibernate 自动映射来映射字典?