コード/コンベンションでNHibernate 3.2マッピングを使用しており、単純な階層ごとのテーブル継承のマッピングに問題があります。私の基本クラスはLookupBaseであり、この基本クラスから派生する十数以上のクラスがあります。クラスモデルをデータベース内の単一のテーブルにマップする必要があります(ディスクリミネータの列にはそれぞれの具象クラスの名前が入ります)。NHibernate 3.2でテーブル階層構造をマップする方法ConventionModelMapper
基本クラスLookupBaseは、具象クラスとは異なるアセンブリにあります。ここで
は、具体的なクラスが実装されている方法です:あなたが見ることができるように
namespace ROWMobile.Domain
{
public class NotificationMethod : LookupBase
{
}
public class ContactMethod : LookupBase
{
}
public class ContactType : LookupBase
{
}
...
、具体的なクラスには、追加のプロパティはありません - 彼らはLookupBaseからすべてのプロパティを継承します。
private HbmMapping GenerateMappings()
{
ConventionModelMapper relationalMapper = new ConventionModelMapper();
var baseLookupType = typeof(LookupBase);
relationalMapper.IsRootEntity((t, declared) => t.BaseType != null && (t.BaseType == typeof(object)));
relationalMapper.IsTablePerClassHierarchy((t, declared) =>
{
if (t == typeof(LookupBase))
{
return true;
}
return false;
});
var mapping = relationalMapper.CompileMappingFor(GetDomainEntities());
return mapping;
}
private static IEnumerable<Type> GetDomainEntities()
{
Assembly domainAssembly = typeof(Event).Assembly;
IList<Type> baseEntities = new List<Type>();
baseEntities.Add(typeof(LookupBase));
IEnumerable<Type> domainEntities = from t in domainAssembly.GetTypes()
where (IsSubclassOfRawGeneric(typeof(LookupBase), t)
&& !t.IsGenericType)
select t;
IEnumerable<Type> allEntities = domainEntities.Concat(baseEntities);
return allEntities;
}
static bool IsSubclassOfRawGeneric(Type generic, Type toCheck)
{
while (toCheck != null && toCheck != typeof(object))
{
var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
if (generic == cur)
{
return true;
}
toCheck = toCheck.BaseType;
}
return false;
}
私はこのような上記のコードを呼び出す:
HbmMapping generatedMappings = GenerateMappings();
System.Diagnostics.Debug.WriteLine(Serialize(generatedMappings));
NhConfiguration.AddDeserializedMapping(generatedMappings, null);
その後、私はスキーマを作成し、テストを持っている:
[TestMethod]
public void GenerateSchema()
{
NHibernateConfigurator nhc = new NHibernateConfigurator();
nhc.BuildSessionFactory<MsSql2008Dialect>();
SchemaExport schemaExport = new SchemaExport(nhc.NhConfiguration);
schemaExport.Execute(true, true, false);
}
私は生産HbmMappingをシリアル化し、XMLた場合、それが見えますこのように:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:nhibernate-mapping-2.2">
<class name="Marathon.MobileApplication.Client.LookupBase, MobileApplication.Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="LookupBases" abstract="true">
<id name="Id" type="Int32" />
<discriminator />
<property name="Value" />
<property name="InternalId" />
</class>
<joined-subclass name="ROWMobile.Domain.NotificationMethod, ROWMobile.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" extends="Marathon.MobileApplication.Client.LookupBase, MobileApplication.Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<key column="notificationmethod_key" />
</joined-subclass>
<joined-subclass name="ROWMobile.Domain.ContactMethod, ROWMobile.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" extends="Marathon.MobileApplication.Client.LookupBase, MobileApplication.Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<key column="contactmethod_key" />
</joined-subclass>
<joined-subclass name="ROWMobile.Domain.ContactType, ROWMobile.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" extends="Marathon.MobileApplication.Client.LookupBase, MobileApplication.Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<key column="contacttype_key" />
</joined-subclass>
....
Discriminatorテーブルを持つLookupBasesテーブルを生成しますが、各具体クラスのテーブルも生成します。誰かが私が間違っていることを教えてもらえますか?また、NHibernate 3.2で導入されたコード/コンベンション機能によるマッピングで利用可能なドキュメントを知っている人はいますか?
提案をいただきありがとうございます。私はFluent NHibernateに切り替えることで実際にこの問題を解決しました。 –