编辑:在帖子末尾添加了 HBM 映射。
我有一个相当大的类库,涉及继承。我正在使用 Fluent NHibernate 将类映射到 MS SQL 2008 以在 Azure 中托管它。
我相当确定映射是正确的。我们使用鉴别器值来区分列(而不是表)上的类。但是,每当我尝试生成映射时,都会收到一个错误,即类/实体之一是重复的。
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();
}
类层次结构是这样的
- 信息
- 评论
- 论坛留言
- 文章
- 图片
- 重击
- 图片
- 文章
Bash 继承自 Image,Image 继承自 Article,以此类推。它们都有不同的鉴别器值。消息映射定义如下:
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>