Расширьте / измените классы NHibernate во время выполнения - PullRequest
4 голосов
/ 04 февраля 2011

Извиняюсь, если уже есть точечный ответ, но я его не нашел.Я использую NH3, и у меня есть сценарий использования, где я хочу добавить Set в любую сущность, класс которой реализует определенный интерфейс.У меня есть класс построителя конфигурации, поэтому я могу внести эти изменения перед созданием фабрики сеансов.

Учитывая этот сокращенный пример:

public class Person : IHasExtraItems
{
    public Person()
    {
        this.ExtraItems = new HashSet<ExtraItem>();
    }
    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; }
    public virtual DateTime Birthdate { get; set; }
    public virtual ICollection<ExtraItem> ExtraItems { get; protected set; }
}

public class ExtraItem
{
    public virtual Guid Id { get; set; }
}

И отображение этого примера:

  <class name="Person">
    <id name="Id">
      <generator class="guid"/>
    </id>
    <property name="Name"/>
    <property name="Birthdate"/>
    <set name="Extra" table="PersonExtraItems" cascade="all">
      <key column="PersonId"/>
      <many-to-many column="ExtraItemId" class="ExtraItem" unique="true" />
    </set>
  </class>

Поскольку я хочу иметь возможность применять эту функциональность ко многим классам прозрачно - просто путем реализации интерфейса - я не хочу помещать «ExtraItem» в отображение.Вместо этого я хочу добавить его во время выполнения.Поэтому, если я удаляю свойство из сопоставления xml, как я могу добавить это во время выполнения?

Там описывается именно тот тип изменения, который я пытаюсь внести: http://ayende.com/Blog/archive/2008/05/01/Dynamic-Mapping-with-NHibernate.aspx

Ноон не отображает множество на множество, и мой слабый мозг не смог расшифровать отображение в памяти, которое nhibernate использует для создания эффекта.Это самое близкое из всех, что я сделал, основанный на попытке получить свойства, видимые в отладчике, чтобы они соответствовали

foreach (var cls in cfg.ClassMappings)
{
    if (typeof(IHasExtraItems).IsAssignableFrom(cls.MappedClass))
    {
        NHibernate.Mapping.Property property = new NHibernate.Mapping.Property();
        NHibernate.Mapping.Set value = new NHibernate.Mapping.Set(cls);
        value.Role = cls.EntityName + ".ExtraItems";
        value.IsGeneric = true;
        var table = new Table();
        table.Name = cls.MappedClass.Name + "ExtraItems";
        value.CollectionTable = table;
        value.GenericArguments = new Type[] { typeof(ExtraItem) };
        value.IsOptimisticLocked = true;
        value.IsLazy = true;
        mappings.AddCollection(value);
        property.Value = value;

        property.Name = "ExtraItems";
        property.PersistentClass = cls;
        property.Cascade = "all";
        cls.AddProperty(property);
    }
}

. В тесте это приводит к ошибке времени выполнения, поскольку ключ имеет значение null, однако версия, сопоставленная с XMLработает и выглядит более или менее идентично во время внесения изменений.

Бонусные баллы : я хочу получить множество ко многим именно потому, что хочу объединенную таблицу.Это позволяет мне сопоставить сущность с расширяющимися данными с истинными внешними ключами для производительности.ExtraItems действительно должен быть типом значения, а не истинной сущностью, но я не мог понять, как отобразить это, даже в XML.

Бонусные баллы, часть 2: Могу ли ясделать это с конформ?Я не хочу переключать все мои существующие сопоставления на confORM, и я не смог найти пример смешивания confORM с обычными XML-отображениями, не говоря уже об изменении существующих отображений.Fluent был бы другим вариантом, но я использую NH3, и я не думаю, что Fluent пока поддерживает это.

Заранее спасибо!

EDIT Я довольноуверен, что моя проблема в том, что я не определяю элементы набора.Однако я не могу понять, как правильно определить элементы набора.

1 Ответ

1 голос
/ 03 марта 2011

Существуют билды свободно для NH3, так что вы можете использовать его (я делаю), и если вы используете свободно, вы можете очень легко сделать это с соглашением.Вы упоминаете об этом в разделе о бонусных баллах, так что, может быть, вам стоит взглянуть на него по-другому?

...