0

编辑:在帖子末尾添加了 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>
4

1 回答 1

1

有人找到原因了。另一个类的映射出现错误:

这就是问题所在:

public class ArticleListMap : SubclassMap<Article>
{
   ArticleListMap()
   {
      DiscriminatorValue(1);
   }
}

public class ArticleMap : SubclassMap<Article>
{
   ArticleMap()
   {
      DiscriminatorValue(4);
      Map(x => x.ExtraText);
      HasManyToMany(x => x.TagSet);
      HasManyToMany(x => x.ImageSet);
   }
}

而不是从SubclassMap<ArticleList>I继承 ArticleListMap SubclassMap<Article>(这是一个打字错误)。由于它们具有不同的鉴别器,但从同一个类继承,确实存在一个重复的映射,而不是“传播”到子类。

于 2013-03-20T13:04:28.573 回答