有一个具有Type属性的类
[Serializable]
public class MeasureTask
{
private Type _typeToStore;
public MeasureTask()
: this(null)
{}
public virtual Type TypeToStore
{
get { return _typeToStore; }
set { _typeToStore= value; }
}
}
此类的FluentNHibernate映射到MSSQL DB。
public class MeasureTaskMap : SubclassMap<MeasureTask>
{
public MeasureTaskMap()
{
Map(x => x.TypeToStore);
}
}
默认情况下,此映射将AssemblyQualifiedName
的{{1}}存储为数据库中的Type
。例如:
string
现在,当程序集编译为更高版本时,例如,
TopNamespace.SubNameSpace.MeasureTask, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b17a5c561934e089
然后Nhibernate尝试从汇编TopNamespace.SubNameSpace.MeasureTask, MyAssembly, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b17a5c561934e089
加载存储在数据库中的Type。但是当前类型已更改为Version=1.0.0.0
,这将导致Version=2.0.0.0
。
现在,如何解决这个问题。我不想手动从AssemblyQualifiedName中剥离版本信息,因为它会产生开销。还有其他标准方法吗?因为,有许多这样的类要映射,这正成为一个突破性的问题。
答案 0 :(得分:0)
您必须手动执行此操作,因为默认实现(NHibernate.Type.TypeType)没有此参数。使用约定(ImmutableUserType see here)的usertype应该很方便。
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>();
}
}