0

编辑 - 快速总结

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

  • <many-to-any />Fluent NHibernate不支持
  • 想要拆分 XML 和 Fluent 之间的属性映射以映射 <many-to-any />关系
  • 发现这可以通过命名查询来实现
  • 当我尝试同时使用 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; }
}

由于 IBar 是一个几乎可以附加到任何类的接口,因此将在中间表上引用的任何“BarID”都可以属于任意数量的其他表。由于这是一个“多对任意”关系,Fluent 仍然不支持它(是的,我知道 NHibernate 的mapping-by-code支持它)。

幸运的是,NHibernate 的 xml 映射仍然可以在使用 Fluent 的项目中轻松使用。不过,我不想在 *.hbm.xml 文件中定义整个映射,我只想映射<many-to-any />. 其余部分,我想保留在 Fluent 映射中(基本上,将映射分成两个文件)。

我知道这对于命名查询和存储过程之类的东西是可能的,但是我在使用这种模式来定义我的关系时遇到了一些麻烦。

这是我的 Foo 类的 Fluent 映射,就像现在一样:

public class FooMap : ClassMap<Foo>
{
    public FooMap()
    {
        Id(x => x.ID);
        Map(x => x.Name);
        Map(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 表和一个 FooBarRelationship 表,其中包含 ID、Foregin Keys 和 BarType 列。但问题是:当我尝试同时使用 xml 和 Fluent 映射时,我得到一个NHibernateDuplicateMappingException. 此外,如果我只对接口使用 XML,而对子类使用 Fluent,则完全忽略 Fluent 映射(即,它就像我只有 xml)。

我已经做了很多搜索,但我无法找到任何可能有帮助的信息。我可以对地图(甚至配置)做些什么来让它工作吗?

4

2 回答 2

0

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

您可能想尝试尽可能多地为该接口及其子类进行流利的映射,然后运行您的应用程序并将配置导出到 hbm 文件。

.Mappings(m =>
{
    m.FluentMappings.ExportTo(@"C:\")
}

从那里修剪到只是接口的映射及其子类,然后添加您的多对任意映射。我不会假装它是一个干净的解决方案,但我不熟悉 nHibernate 映射的深层内部结构,以了解它如何合并来自 hbm 文件的映射与流畅或冗长的映射之类的东西。

我不确定你还能尝试什么,除了切换到 nHibernate 的 loquacious 映射(如果不是因为它们不支持多对多映射上的 where 子句,我也很想尝试)。

于 2013-05-01T16:08:16.913 回答
0

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

缺点是它需要对您的域结构进行轻微修改,但 IMO 它比尝试导出和操作 FluentNHibernate 生成的 XML 更优雅。

于 2019-08-19T14:11:13.737 回答