C# 不带版本信息的Fluent nhibernate映射类型

C# 不带版本信息的Fluent nhibernate映射类型,c#,nhibernate,fluent-nhibernate,nhibernate-mapping,fluent-nhibernate-mapping,C#,Nhibernate,Fluent Nhibernate,Nhibernate Mapping,Fluent Nhibernate Mapping,有一个类具有类型属性 [Serializable] public class MeasureTask { private Type _typeToStore; public MeasureTask() : this(null) {} public virtual Type TypeToStore { get { return _typeToStore; } set { _typeToStore= valu

有一个类具有类型属性

[Serializable]
public class MeasureTask
{
    private Type _typeToStore;

    public MeasureTask()
        : this(null)
    {}

    public virtual Type TypeToStore
    {
        get { return _typeToStore; }
        set { _typeToStore= value; }
    }
}
此类到MSSQL DB的FluentNHibernate映射

public class MeasureTaskMap : SubclassMap<MeasureTask>
{
  public MeasureTaskMap()
  {    
    Map(x => x.TypeToStore);
  }
}
公共类MeasureTaskMap:子类映射
{
公共度量askmap()
{    
Map(x=>x.TypeToStore);
}
}
默认情况下,此映射将
类型的
AssemblyQualifiedName
存储为数据库中的
字符串。例如:

TopNamespace.SubNameSpace.MeasureTask,MyAssembly,版本=1.0.0.0,区域性=neutral,PublicKeyToken=b17a5c561934e089

现在,当程序集编译为更高版本时,例如

TopNamespace.SubNameSpace.MeasureTask,MyAssembly,版本=2.0.0.0,区域性=中性,PublicKeyToken=b17a5c561934e089

然后Nhibernate尝试从存储在数据库中的程序集
Version=1.0.0.0
加载类型。但是当前类型已更改为
Version=2.0.0.0
,这将导致
TypeNotFoundException


现在,如何解决这个问题。我不想手动从AssemblyQualifiedName中删除版本信息,因为它会产生开销。有没有其他标准的方法可以做到这一点?因为,有许多这样的类需要映射,这正在成为一个突破性的问题。

您必须手动进行映射,因为默认实现(NHibernate.Type.TypeType)没有用于映射的参数。使用约定应用的用户类型(ImmutableUserType)应该很方便

public class VersionAgnosticType : ImmutableUserType 
{
    public override object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        var typename = TypeNameParser.Parse((string)NHibernateUtil.String.Get(rs, names[0])));
        return Type.GetType(typename.Type + ", " + new AssemblyName(typename.Assembly).Name);
    }

    public override void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        var type = (Type)value;
        NHibernateUtil.String.Set(cmd, type.FullName + "," + type.Assembly.GetName().Name, index);
    }

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

    public override SqlType[] SqlTypes
    {
        get { return new[] { SqlTypeFactory.GetString(255) }; }
    }
}

public class TypePropertyConvention : IPropertyConvention
{
    public void Apply(IPropertyInstance instance)
    {
        if (instance.Type == typeof(Type))
            instance.CustomType<VersionAgnosticType>();
    }
}
public类versionAgonisticType:ImmutableUserType
{
公共重写对象NullSafeGet(IDataReader rs,字符串[]名称,对象所有者)
{
var typename=TypeNameParser.Parse((string)NHibernateUtil.string.Get(rs,names[0]);
返回Type.GetType(typename.Type+“,”+新程序集名称(typename.Assembly.Name);
}
public override void NullSafeSet(IDbCommand cmd,对象值,int索引)
{
变量类型=(类型)值;
NHibernateUtil.String.Set(cmd,type.FullName+”,“+type.Assembly.GetName().Name,index);
}
公共重写类型ReturnedType
{
获取{return typeof(Type);}
}
公共重写SqlType[]SqlTypes
{
获取{returnnew[]{SqlTypeFactory.GetString(255)};}
}
}
公共类类型PropertyConvention:IPropertyConvention
{
公共无效应用(IPropertyInstance实例)
{
if(instance.Type==typeof(Type))
CustomType();
}
}

它的用途是什么?我将TypePropertyConvention添加到AutoPersistenceModel中的约定列表中。我们应该为属性使用此类型而不是System.Type吗?那么我们如何映射属性呢?当然,VersionAgnosticType不能强制转换为System.Type。VersionAgnosticType是一个IUserType,负责将Type属性的值转换为数据库表示形式,而域模型对此没有任何连接/知识。该约定基本上是说“存储类型对象的所有属性都将由VersionAgnosticType序列化”,谢谢,它现在几乎可以工作了。我加了几张支票。因为有时NullSafeGet()的names[]参数将此wierd字符串“SourceType_80_0_”作为typeName,因此NHibernateUtil.string.Get()无法解析它并返回空字符串。这是一个问题吗?
SourceType\u 80\u 0\u
是NHibernate为该列提供的别名,用于区分它,因为可能存在自联接,并且同一列返回两次。作为列的索引,它在结果集中应始终有效。如果从
NHibernateUtil.string.Get
返回string.empty,则该列很可能包含一个空字符串。您可以执行
rs[names[0]]
并查看原始返回值