Свободное отображение типов nhibernate без информации о версии

1

Существует класс с свойством 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 Type в виде string в db. Например:

TopNamespace.SubNameSpace.MeasureTask, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b17a5c561934e089

Теперь, когда сборка скомпилирована в более высокую версию, например,

TopNamespace.SubNameSpace.MeasureTask, MyAssembly, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b17a5c561934e089

Затем Nhibernate пытается загрузить Type из сборки Version=1.0.0.0 которая хранится в базе данных. Но текущий тип был изменен на Version=2.0.0.0 и это приведет к TypeNotFoundException.

Теперь, как обойти эту проблему. Я не хочу вручную отключать информацию о версии из AssemblyQualifiedName, поскольку она создает накладные расходы. Есть ли другой стандартный способ сделать это? Потому что есть много классов, подобных этому, и это становится проблемой.

Теги:
nhibernate
fluent-nhibernate
nhibernate-mapping
fluent-nhibernate-mapping

1 ответ

0

Вы должны сделать это вручную, потому что для реализации по умолчанию (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>();
    }
}
  • 0
    Что такое использование? Я добавил TypePropertyConvention в список соглашений в AutoPersistenceModel. Должны ли мы использовать этот тип вместо System.Type для свойства? Тогда как мы сопоставляем недвижимость? Конечно, VersionAgnosticType не может быть приведен как System.Type.
  • 0
    VersionAgnosticType - это IUserType, который отвечает за преобразование значения Type-Property в представление базы данных и обратно, ваша модель домена не имеет никакого отношения к нему / знания о нем вообще. Соглашение в основном гласит: «все свойства, в которых хранится объект Type, будут сериализованы VersionAgnosticType»
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню