5

私はディスクリミネータで継承をマップしようとしていますが、サブクラスにはディスクリミネータ値はありません。オートマッピングを使ってそれを解決するには?流暢なNHibernateの自動マッピングとディスクリミネータ

ドメインオブジェクトは、次のとおりです。

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> 

答えて

7

私はこれが機能することを発見:

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 
} 

このシナリオでは、Invoiceクラスから派生したSalesInvoiceクラスがあります。現在のサブクラスがInvoiceから派生している場合、サブクラスの受け入れ基準は真です。 Discriminatorの値は、サブクラスのタイプに基づいて割り当てられます。ご覧のとおり、名前を使用して型を比較します。残念ながら何らかの理由でsubclass.EntityTypeプロパティが実行時にnullであるため、型を直接比較できません。

関連する問題