C# 使用映射或模拟与Fluent NHibernate的多对多关系的选项?

C# 使用映射或模拟与Fluent NHibernate的多对多关系的选项?,c#,nhibernate,fluent-nhibernate,C#,Nhibernate,Fluent Nhibernate,编辑-快速摘要 我意识到我有相当多的文字,所以这里是问题的简要总结: 是 要在XML和Fluent之间拆分属性映射以映射关系吗 发现这是可能的 当尝试将XML和Fluent用于我的界面时,我得到了一个NHibernateDuplicateMappingException 当尝试仅使用XML作为接口,使用Fluent作为我的子类时,XML映射将其映射到数据库,但忽略Fluent 因为我已经定义了大量的约定,所以我不希望在这个类层次结构中只使用XML 此外,如果有人知道在Fluent中使用多对多

编辑-快速摘要

我意识到我有相当多的文字,所以这里是问题的简要总结:

  • 要在XML和Fluent之间拆分属性映射以映射
    关系吗
  • 发现这是可能的
  • 当尝试将XML和Fluent用于我的界面时,我得到了一个
    NHibernateDuplicateMappingException
  • 当尝试仅使用XML作为接口,使用Fluent作为我的子类时,XML映射将其映射到数据库,但忽略Fluent
因为我已经定义了大量的约定,所以我不希望在这个类层次结构中只使用XML

此外,如果有人知道在Fluent中使用多对多的替代方案,我非常愿意尝试一下。


编辑-完整问题和代码示例

我有两个类(我们称它们为“Foo”和“Bar”),它们共享多对多关系。通常,用Fluent-this映射它就像将
HasManyToMany(x=>x.SomeProperty)
抛出到我的类映射中一样简单;但是,我的一个接口遇到了问题

以下是对象的基本设置示例供参考:

public class Foo
{
    public virtual long ID { get; set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual IList<IBar> Bars { get; set; }
}

public interface IBar
{
    long ID { get; set; }
    IList<Foo> Foos { get; set; }
}
公共类Foo
{
公共虚拟长ID{get;set;}
公共虚拟字符串名称{get;set;}
公共虚拟字符串描述{get;set;}
公共虚拟IList条{get;set;}
}
公共接口IBar
{
长ID{get;set;}
IList Foos{get;set;}
}
由于IBar是一个可以附加到几乎任何类的接口,因此中间表上引用的任何“BarID”都可以属于任意数量的其他表。因为这是一种关系,它是(是的,我知道这是由NHibernate的支持)

幸运的是,NHibernate的xml映射仍然可以在使用Fluent的项目中轻松使用。但是,我不想在*.hbm.xml文件中定义整个映射,我只想映射
。剩下的部分,我想保留在Fluent映射中(基本上,将映射拆分为两个文件)

我知道这是可能的,但我在使用这种模式来定义我的关系时遇到了一些麻烦

以下是我的Foo类的Fluent映射:

public class FooMap : ClassMap<Foo>
{
    public FooMap()
    {
        Id(x => x.ID);
        Map(x => x.Name);
        Map(x => x.Description);
    }
}
公共类FooMap:ClassMap
{
公共地图()
{
Id(x=>x.Id);
Map(x=>x.Name);
映射(x=>x.Description);
}
}
这里是Foo.hbm.xml文件:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="MyProject" namespace="MyProject.Entities">
    <class name="Foo" table="Foos"> 
        <id name="ID">      
            <generator class="identity" />
        </id>
        <bag name="Bars" table="FooBarRelationship">
            <key column="ID" />
            <many-to-any id-type="System.Int64" meta-type="System.String">
                <column name="BarID" />
                <column name="BarType" />
            </many-to-any>
        </bag>
    </class>
</hibernate-mapping>

就其本身而言,这两种方法都很好。例如,如果我只是使用Fluent映射,那么我的Foo表将使用三个映射列生成。类似地,如果我只使用xml,那么NHibernate将创建一个具有ID的Foo表和一个具有ID、Foregin键和BarType列的FooBarRelationship表。但问题是:当我尝试同时使用xml和Fluent映射时,我得到了一个
NHibernateDuplicateMappingException
。此外,如果我只对接口使用XML,而对子类使用Fluent,则Fluent映射将被完全忽略(即,它就像我只有XML一样)


我已经做了很多搜索,但是没有找到任何可能有用的信息。我可以对映射(甚至配置)做些什么来让它工作吗?

我认为您可能最终不得不将整个Foo映射(和子类)放在XML文件中。我相信你是对的,你可以将fluent映射和hbm映射结合起来,但我不相信你可以将它们用于同一个实体,也许这也适用于子类?当根类(或接口)映射通过不同于子类的方式定义时,它似乎遇到了问题

您可能希望尝试在fluent中为该接口及其子类执行尽可能多的映射,然后运行应用程序并将配置导出到hbm文件

.Mappings(m =>
{
    m.FluentMappings.ExportTo(@"C:\")
}
从这里开始,将其精简为接口及其子类的映射,然后将多个映射添加到任何映射中。我不想假装这是一个干净的解决方案,但我不熟悉nHibernate映射的深层内涵,无法理解它是如何将hbm文件中的映射与流畅或冗长的映射合并在一起的


我不知道你还可以尝试什么,除了切换到nHibernate的冗长的映射(如果不是因为他们缺乏对多对多映射where子句的支持,我也尝试过这种映射)。

我遇到了同样的问题,并提出了一个半优雅的解决方案。无法在.hbm.xml文件中流畅地映射同一类。但是,可以单独映射子类。我的解决方案是创建一个抽象的FooBase类,该类被流畅地映射并包含除FluentNHibernate不支持的特性之外的所有内容。然后,创建一个继承FooBase的具体Foo类,并将该Foo类(仅不支持的特性)映射到.hbm.xml文件中


缺点是它需要对域结构稍作修改,但在我看来,它比尝试导出和操作FluentNHibernate生成的XML更优雅。

是的,我想导出整个层次结构的hbm,我只是一直在尝试避免它。如果这是一个选项,我会尝试切换到NHibernate的华丽映射。也许我可以用复合类型做一些疯狂的事情。