编辑 - 快速摘要
我意识到我有相当多的文字,所以这里有一个问题的快速摘要:
<many-to-any />
是unsupported by Fluent NHibernate <many-to-any />
关系NHibernateDuplicateMappingException
由于我定义了大量约定,因此我不希望仅对此类层次结构使用XML。
此外,如果有人知道在Fluent中使用多对多的替代解决方案,我会非常愿意尝试一下。
编辑 - 完整问题和代码示例
我有两个分享多对多关系的课程(我们称之为“Foo”和“Bar”)。通常情况下,使用Fluent进行映射就像在我的类地图中抛出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”都可以属于任意数量的其他表。由于这是一个"many-to-any"关系,它是still unsupported by Fluent(是的,我知道这是由NHibernate的mapping-by-code支持的。)
幸运的是,NHibernate的xml映射仍然可以在使用Fluent的项目中轻松使用。不过,我不想在* .hbm.xml文件中定义整个地图,而只想映射<many-to-any />
。其余部分,我想保留在Fluent地图中(基本上,将映射分成两个文件)。
我知道named queries and stored procedures这样的事情是可行的,但我在使用这种模式来定义我的关系时遇到了一些麻烦。
这是我现在的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和FooBarRelationship表的Foo表,其中包含ID,Foregin Keys和BarType列。不过这是问题所在:当我尝试同时使用xml和Fluent映射时,我得到NHibernateDuplicateMappingException
。另外,如果我只使用XML作为接口,但是使用Fluent作为子类,则完全忽略Fluent映射(即,它就像我只有xml一样)。
我已经做了很多搜索,但我找不到任何可能有用的信息。我可以对地图(甚至配置)做些什么来实现这个目的吗?
答案 0 :(得分:0)
我认为您可能最终必须将整个Foo映射(和子类)放在XML文件中。我相信你是对的,你可以结合流畅的映射和hbm映射,但我不相信你可以在同一个实体时这样做,也许这也适用于子类?当通过与子类不同的方式定义根类(或接口)映射时,它似乎遇到了问题。
您可能想尝试为该接口执行尽可能多的映射,并使用流畅的子类,然后运行您的应用并将配置导出到hbm文件。
.Mappings(m =>
{
m.FluentMappings.ExportTo(@"C:\")
}
从那里把它修剪成接口的映射和它的子类,然后添加你的多对多映射。我不打算假装它是一个干净的解决方案,但我不熟悉nHibernate映射的深层内部,以了解它如何合并来自hbm文件的映射与流畅或喋喋不休的映射之类的东西。
我不确定你还能尝试什么,除了切换到nHibernate的loquacious映射(我一直试图尝试它不是因为他们缺乏对多对多映射中where子句的支持)。
答案 1 :(得分:0)
我遇到了同样的问题,并提出了一个半优雅的解决方案。不能流畅地在.hbm.xml文件中映射相同的类。但是,您可以 单独映射一个子类。我的解决方案是创建一个抽象的FooBase类,该类可以流畅地映射并包含FluentNHibernate不支持的功能以外的所有内容。然后,创建一个继承FooBase的具体Foo类,并将该Foo类(仅不受支持的功能)映射到.hbm.xml文件中。
不利之处在于,它需要对您的域结构进行一些修改,但是IMO尝试导出和处理FluentNHibernate生成的XML会更优雅。