首页 文章

使用NHibernate 1.2映射System.Version

提问于
浏览
3

我有一个使用System.Version作为属性的对象 . 我希望将此对象映射到我的表中,将该版本存储为字符串 . 使用NHibernate v1.2进行此操作的最佳方法是什么?

public class MyClass
{
  public Version MyVersion {get; set;}
}

不知道如何处理有关的映射

<property name =“MyVersion”column =“MyVersion”not-null =“true”/>

这给了我错误说“在列'MyVersion0_0_'上无效尝试GetBytes . GetBytes函数只能用于Text,NText或Image类型的列 . ”如果我在 Map 中使用type =“string”,则会出现投射错误 .

建议?

4 回答

  • 2

    您需要编写一个NHibernate用户类型,它返回类型为Version的属性值,但仍以字符串形式存在 . 有一个框架用户类型实现here,它为您处理一些工作 .

  • 0

    David M的建议和文章链接都很棒 . 以防万一其他人在访问该网站时遇到问题(我不得不从谷歌缓存中加载),这是我的解决方案:

    public abstract class BaseImmutableUserType : IUserType
        {
            public abstract object NullSafeGet(IDataReader rs, string[] names, object owner);
            public abstract void NullSafeSet(IDbCommand cmd, object value, int index);
            public abstract SqlType[] SqlTypes { get; }
    
            public new bool Equals(object x, object y)
            {
                if (ReferenceEquals(x, y))
                {
                    return true;
                }
    
                if (x == null || y == null)
                {
                    return false;
                }
    
                return x.Equals(y);
            }
    
            public int GetHashCode(object x)
            {
                return x.GetHashCode();
            }
    
            public object DeepCopy(object value)
            {
                return value;
            }
    
            public object Replace(object original, object target, object owner)
            {
                return original;
            }
    
            public object Assemble(object cached, object owner)
            {
                return DeepCopy(cached);
            }
    
            public object Disassemble(object value)
            {
                return DeepCopy(value);
            }
    
            public Type ReturnedType
            {
                get { return typeof(T); }
            }
    
            public bool IsMutable
            {
                get { return false; }
            }
        }
    
        public class VersionUserType: BaseImmutableUserType
        {
    
            public override SqlType[] SqlTypes 
            { 
                get
                {
                    return new SqlType[]{new StringSqlType()};
                } 
            }
    
            public override object NullSafeGet(IDataReader rs, string[] names, object owner)
            {
                Version version = null;
                var value = NHibernateUtil.String.NullSafeGet(rs, names) as string;
                if (value != null)
                    version = new Version(value);
                return version;
            }
    
            public override void NullSafeSet(IDbCommand cmd, object value, int index)
            {
                object valueToSet;
                Version version = value as Version;
                if (version != null)
                {
                    valueToSet = version.ToString();
                }
                else
                {
                    valueToSet = DBNull.Value;
                }
    
                NHibernateUtil.String.NullSafeSet(cmd, valueToSet, index);
            }
        }
    

    并且映射文件现在具有以下属性:

    <property name =“MyVersion”column =“MyVersion”not-null =“true”type =“My.Namespace.VersionUserType,My.Assembly”/>

  • 4

    David M的另一个大拇指's answer. However, you' ll请注意 System.Version 有一个构造函数,它接受一个字符串表示,以及产生相同格式的 ToString() ,因此您可以将该属性映射为NHibernate中的简单字符串并将其映射到私有直接字符串字段,然后有一个类型为System.Version的facade属性,如下所示:

    public System.Version Version
    {
        get { return new System.Version(_versionAsString); }
        set { _versionAsString = value.ToString(); }
    }
    

    我并不认为它特别糟糕,而且很容易做到 . 如果您要为延迟加载代理类型,则可能需要使用内部属性而不是字段,否则它应该起作用 .

  • 2

    大卫M的答案可能是最强有力的方法 .

    作为替代方案,您可以将属性转换为字符串并使用它 . 我不确定你模型中的变化有多大 .

相关问题