Свободное автоматическое отображение NHibernate с дискриминатором - PullRequest
5 голосов
/ 10 ноября 2009

Я пытаюсь отобразить наследование с помощью дискриминатора, но подклассы не имеют значения дискриминатора. Как решить это с помощью AutoMappings?

Доменные объекты выглядят следующим образом:

public abstract class Item : GuidIdentityEntity {
   public virtual string Name { get; set; }
}

public class Product : Item {}
public class RawMaterial : Item {}

Конфигурация выглядит так:

AssemblyOf<Item>()
    .IgnoreBase<GuidIdentityEntity>();
    .IncludeBase<Item>();
    .Setup(setup => {
        setup.DiscriminatorColumn = type => "Discriminator";
        setup.IsDiscriminated = type => type == typeof(Item);
        setup.SubclassStrategy = type => (type == typeof(Item)) 
            ? SubclassStrategy.Subclass 
            : SubclassStrategy.JoinedSubclass;
    });

Результат сопоставлений:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
  <class xmlns="urn:nhibernate-mapping-2.2" name="Solution.Core.Products.Item, Solution.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2e5ef41be3839ad7" table="`Item`">
    <id name="Id" type="System.Guid, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Id" />
      <generator class="guid.comb" />
    </id>
    <discriminator type="String">
      <column name="Discriminator" />
    </discriminator>
    <property name="Name" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Name" />
    </property>
    <subclass name="Solution.Core.Products.RawMaterial, Solution.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2e5ef41be3839ad7" />
    <subclass name="Solution.Core.Products.Product, Solution.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2e5ef41be3839ad7" />
  </class>
</hibernate-mapping>

1 Ответ

7 голосов
/ 13 ноября 2009

Я обнаружил, что это работает:

    public class SubclassConvention : ISubclassConvention, ISubclassConventionAcceptance
{
    #region IConvention<ISubclassInspector,ISubclassInstance> Members

    public void Apply(ISubclassInstance instance)
    {
        if (instance.Name == typeof(SalesInvoice).AssemblyQualifiedName)
            instance.DiscriminatorValue("SAL");
    }

    #endregion

    #region IConventionAcceptance<ISubclassInspector> Members

    public void Accept(IAcceptanceCriteria<ISubclassInspector> criteria)
    {
        criteria.Expect(subclass => Type.GetType(subclass.Name).BaseType == typeof(Invoice));
    }

    #endregion
}

В этом сценарии у меня есть класс SalesInvoice, производный от класса Invoice. Критерии приемлемости для подкласса верны, когда текущий подкласс получен из счета-фактуры. Значение дискриминатора присваивается в зависимости от типа подкласса. Как видите, я сравниваю типы, используя имена. К сожалению, по какой-то причине свойство subclass.EntityType имеет значение null во время выполнения, поэтому я не могу сравнивать типы напрямую.

...