是否有可能使用NHibernate的sqlite的清单打字功能?(is it possible to

2019-07-31 04:51发布

这是张贴在hibernate.org上论坛和nhusers名单没有太多的运气,所以我想我会尝试在这里。

简单地说,假设我有一个类:

class A
{
   public virtual object SomeValue { get; set; }
}

someValue中的类型基本上是在集.NET IConvertible类型(基元像布尔,字节,字符,INT16,双,浮动等),加上字节[]和字符串。

我想创建一个NHibernate的映射为一个以反映这一 - 这样我就可以基本设置someValue中以任意对象(上面的类型之一)和检索后来上。 然后我AppLogic的将反映在它找到的类型和相应的行为。

到目前为止,我已经尝试创建IUserType的实现,试图处理这个问题。 但是我不知道是什么,返回该SQLTYPE []的SQLType。 我认为新的SQLTYPE(DbType.Object),但是当我尝试生成这个架构,我得到一个System.ArgumentException:方言不支持DbType.Object

如果我尝试另一种数据类型,然后我试图转换的类型时,得到了各种各样的造型异常。 例如,如果我使用DbType.Binary,并设置someValue中为Int32,在尝试提交我得到System.InvalidCastException:无法投类型“System.Int32”的对象键入“System.Byte []”。

有没有一种方法来实现这一目标?

下面附代码IUserType的非工作实现(基于http://intellect.dk/post/Implementing-custom-types-in-nHibernate.aspx )

public class DataElementType : IUserType

    {
        SqlType baseType = new SqlType(DbType.Binary);
        public SqlType[] SqlTypes
        {
            get
            {
                return new[] { baseType };
            }
        }

        public System.Type ReturnedType
        {
            get { return typeof(object); }
        }

        public new bool Equals(object x, object y)
        {
            if (x == null)
                return false;
            else
                return x.Equals(y);
        }

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

        public object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            return rs[names[0]];
        }

        public void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            var param = new SQLiteParameter(baseType.DbType, value);
            cmd.Parameters.Insert(index, param);
        }

        public object DeepCopy(object value)
        {
            if (value == null) return null;
            return value;
        }

        public bool IsMutable
        {
            get { return false; }
        }

        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;
        }
    }

Answer 1:

事实证明,以避开与SQLTYPE(DbType.Object)问题是由方言不支持的,我们将其通过继承有明确的支持SQLiteDialect支持:

public class SQLiteDialectWithManifestTyping : SQLiteDialect
{
    public SQLiteDialectWithManifestTyping() : base()
    {
        base.RegisterColumnType(DbType.Object, "NONE");
    }
}

要使用此方言流利,你SQLiteConfiguration对象调用方言()。 在NHibernate中,appropriatelly设置配置属性方言(见裁判手册的3.5.1节)。

然后,我们可以申请我们的映射(需要到的SQLType定义修改为这个上面DataElementType实现:

    public SqlType[] SqlTypes
    {
        get
        {
            return new[] { new SqlType(DbType.Object) };
        }
    }

笔记:

  1. 它不是完美的。 还有就是要上溯造型所有离散号码的Int64的趋势,漂浮翻番。

  2. 还有就是要存储大的无符号值(例如ULONG> = long.MaxValue的值)没有含蓄的方式,但是这是一个普遍的问题源码(以及可能的一般ado.net的问题?)。

  3. 由于编译时检查它的损失可能是desireable把一些运行时检查在NullSafeSet方法,以确保该值是一个基本类型。 试图存储一般对象似乎只是导致调用对象的ToString()方法。



文章来源: is it possible to use sqlite manifest typing features in nhibernate?