編集:投稿の最後にHBMマッピングを追加しました。
私はかなり大きなクラスライブラリを持っており、継承が関係しています。FluentNHibernateを使用してクラスをMSSQL2008にマップし、これをAzureでホストしています。
マッピングが正しいと確信しています。Discriminator Valueを使用して、(テーブルではなく)列のクラスを区別します。ただし、マッピングを生成しようとすると、クラス/エンティティの1つが重複しているというエラーが表示されます。
Duplicate class/entity mapping FolkeLib.MMOBash.Bash
これはここで起こります:
private static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(
MsSqlConfiguration.MsSql2008.Dialect("NHibernate.Dialect.MsSql2008Dialect")
.ConnectionString(c =>
c.FromConnectionStringWithKey("FolkeConnString"))
.ShowSql())
.Mappings(m =>
m.FluentMappings.AddFromAssemblyOf<Account>())
.ExposeConfiguration(cfg =>
new SchemaUpdate(cfg).Execute(false, true))
.Diagnostics(diag => diag.Enable().OutputToConsole())
.BuildSessionFactory();
}
クラス階層は次のようなものです
- メッセージ
- コメント
- ForumMessage
- 記事
- 画像
- バッシュ
- 画像
- 記事
Bashは、Articleから継承するImageから継承します。それらはすべて異なる弁別値を持っています。メッセージマッピングは次のように定義されます。
public class MessageMap : ClassMap<Message>
{
MessageMap()
{
Id(x => x.Id);
DiscriminateSubClassesOnColumn("MessageType").SqlType("int32");
Map(x => x.CreationDate).Index("ArticleCreationDate");
Map(x => x.ModificationDate);
Map(x => x.LastChildCreationDate);
References(x => x.Author);
References(x => x.RootMessage).Nullable(); ;
References(x => x.ParentMessage).Nullable(); ;
}
}
(より多くのプロパティがありますが、それらは無関係だと思います)。RootMessageとParentMessagesは、それ自体が「メッセージ」タイプであることに注意してください。これが根本的な原因でしょうか?
Bashマッピングは次のようになります。
public class BashMap : SubclassMap<Bash>
{
BashMap()
{
DiscriminatorValue(5);
Map(x => x.Game);
Map(x => x.Language);
References(x => x.ApprovedBy);
}
}
私はこれに何時間も費やしましたが、なぜ重複クラス/エンティティマッピングエラーが発生するのかわかりません。
編集:トラブルシューティングの更新。
以下の提案に従って、このコードを追加しました。
public ActionResult Zogzog()
{
List<string> types = new List<string>();
foreach (var module in typeof(Account).Assembly.GetModules())
{
foreach (var type in module.GetTypes())
{
if (typeof(IMappingProvider).IsAssignableFrom(type))
{
types.Add(type.ToString());
}
}
}
ViewBag.Types = types;
return View();
}
ビューの出力は次のとおりです。
FolkeLib.Calendar.EventRoleMap
FolkeLib.Calendar.LocationMap
FolkeLib.Calendar.RegistrationMap
FolkeLib.Calendar.RoleMap
FolkeLib.Domain.AccountMap
FolkeLib.Domain.AccountBanMap
FolkeLib.Domain.CommunityMap
FolkeLib.Domain.ContactEntryMap
FolkeLib.Domain.ContactTypeMap
FolkeLib.Domain.ForumMap
FolkeLib.Domain.ReadMessageMap
FolkeLib.Domain.RssFeedMap
FolkeLib.Domain.SkinMap
FolkeLib.Domain.GroupMap
FolkeLib.Domain.LanguageMap
FolkeLib.Domain.MenuMap
FolkeLib.Domain.MenuItemMap
FolkeLib.Domain.MessageMap
FolkeLib.Domain.PollMap
FolkeLib.Domain.PollAnswerMap
FolkeLib.Domain.PollVoteMap
FolkeLib.Domain.QuoteMap
FolkeLib.Domain.MessageReportMap
FolkeLib.Game.CharacterMap
FolkeLib.Domain.RssChannelMap
FolkeLib.Domain.SiteMap
FolkeLib.Domain.SiteApplicationModuleMap
FolkeLib.Domain.StaticTextMap
FolkeLib.Domain.TagMap
FolkeLib.Domain.VoteMap
重複はないようですが、Messageの子は表示されないようです。それが正常であるかどうかはわかりませんが(SubclassMapタイプであり、ここに表示されているのはClassMapタイプです)、これはコメントで尋ねられました。
編集:これはFluentによって生成されたMessage.hbm.xmlファイルです。ご覧のとおり、一部のクラス(Bash、Article、...)は、サブクラスとして何度か表示され、場合によっては異なる識別子の値が使用されます。
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class xmlns="urn:nhibernate-mapping-2.2" name="FolkeLib.Domain.Message, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Message`">
<id name="Id" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Id" />
<generator class="identity" />
</id>
<discriminator type="String">
<column name="MessageType" sql-type="int32" />
</discriminator>
<property name="CreationDate" type="System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="CreationDate" index="ArticleCreationDate" />
</property>
<property name="ModificationDate" type="System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="ModificationDate" />
</property>
<property name="LastChildCreationDate" type="System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="LastChildCreationDate" />
</property>
<property name="Text" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Text" />
</property>
<property name="Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Locked" />
</property>
<property name="Score" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Score" />
</property>
<property name="Hidden" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Hidden" />
</property>
<property name="Deleted" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Deleted" />
</property>
<property name="AuthorIp" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="AuthorIp" />
</property>
<property name="PublicationDate" type="System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="PublicationDate" />
</property>
<many-to-one class="FolkeLib.Domain.Account, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Author">
<column name="Author_id" />
</many-to-one>
<many-to-one class="FolkeLib.Domain.Account, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Locker">
<column name="Locker_id" not-null="false" />
</many-to-one>
<many-to-one class="FolkeLib.Domain.Message, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="RootMessage">
<column name="RootMessage_id" not-null="false" />
</many-to-one>
<many-to-one class="FolkeLib.Domain.Message, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="ParentMessage">
<column name="ParentMessage_id" not-null="false" />
</many-to-one>
<many-to-one class="FolkeLib.Domain.Site, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Site">
<column name="Site_id" not-null="true" />
</many-to-one>
<many-to-one class="FolkeLib.Domain.Forum, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Forum">
<column name="Forum_id" />
</many-to-one>
<many-to-one class="FolkeLib.Domain.Account, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="DeletedBy">
<column name="DeletedBy_id" />
</many-to-one>
<subclass name="FolkeLib.Domain.Comment, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="2" />
<subclass name="FolkeLib.Domain.ForumMessage, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="3">
<property name="Title" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Title" />
</property>
<subclass name="FolkeLib.Calendar.Event, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="6">
<bag lazy="true" name="RoleSet" table="EventEventRole">
<key>
<column name="Event_id" />
</key>
<many-to-many class="FolkeLib.Calendar.EventRole, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<column name="EventRole_id" />
</many-to-many>
</bag>
<property name="Duration" type="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Duration" />
</property>
<property name="RecurringDays" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="RecurringDays" />
</property>
<property name="FirstTime" type="System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="FirstTime" />
</property>
<property name="LastTime" type="System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="LastTime" />
</property>
<many-to-one class="FolkeLib.Calendar.Location, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Location">
<column name="Location_id" />
</many-to-one>
</subclass>
<subclass name="FolkeLib.Domain.Article, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="1">
<subclass name="FolkeLib.Domain.Image, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="1">
<property name="Name" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Name" />
</property>
<property name="Extension" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Extension" />
</property>
<property name="Public" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Public" />
</property>
<property name="ForAdults" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="ForAdults" />
</property>
<subclass name="FolkeLib.MMOBash.Bash, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="5">
<property name="Game" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Game" />
</property>
<property name="Language" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Language" />
</property>
<many-to-one class="FolkeLib.Domain.Account, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="ApprovedBy">
<column name="ApprovedBy_id" />
</many-to-one>
</subclass>
</subclass>
</subclass>
<subclass name="FolkeLib.Domain.Article, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="4">
<bag name="TagSet" table="TagToArticle">
<key>
<column name="Article_id" />
</key>
<many-to-many class="FolkeLib.Domain.Tag, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<column name="Tag_id" />
</many-to-many>
</bag>
<bag name="ImageSet" table="ImageToArticle">
<key>
<column name="Article_id" />
</key>
<many-to-many class="FolkeLib.Domain.Image, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<column name="Image_id" />
</many-to-many>
</bag>
<property name="ExtraText" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="ExtraText" />
</property>
<subclass name="FolkeLib.Domain.Image, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="1">
<property name="Name" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Name" />
</property>
<property name="Extension" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Extension" />
</property>
<property name="Public" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Public" />
</property>
<property name="ForAdults" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="ForAdults" />
</property>
<subclass name="FolkeLib.MMOBash.Bash, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="5">
<property name="Game" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Game" />
</property>
<property name="Language" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<column name="Language" />
</property>
<many-to-one class="FolkeLib.Domain.Account, FolkeLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="ApprovedBy">
<column name="ApprovedBy_id" />
</many-to-one>
</subclass>
</subclass>
</subclass>
</subclass>
</class>
</hibernate-mapping>