Fluent NHibernate 自动映射:一对多实体,多对多后端?

Posted

技术标签:

【中文标题】Fluent NHibernate 自动映射:一对多实体,多对多后端?【英文标题】:Fluent NHibernate automapping: One-to-many entities, many-to-many backend? 【发布时间】:2012-03-03 10:42:54 【问题描述】:

我的目标是使用 NHibernate 模式生成以及 Fluent NHibernate 的自动映射器来生成我的数据库。我遇到了我称之为“单向多对多关系”的问题。

我的许多实体都有本地化资源。单个类可能如下所示:

public class Something 
  public virtual int Id get; private set;
  public virtual Resource Title get;set;
  public virtual Resource Description get;set;
  public virtual IList<Resource> Bullets get;set;

Resource 类没有返回任何引用;这些完全是单向的。

public class Resource 
    public virtual int Id get; private set;
    public virtual IList<LocalizedResource> LocalizedResources get;set;
    // etc.

public class LocalizedResource  // 
    public virtual int Id get; private set; 
    public virtual string CultureCode get;set;
    public virtual string Value get;set;
    public virtual Resource Resource get;set;

如果没有IList&lt;Resource&gt;,一切都会按照我的意愿生成——资源ID 在TitleDescription 字段中。但是,当我添加 IList 时,NHibernate 会将字段 something_id 添加到 Resource 表中。我理解它为什么这样做,但在这种情况下,这不是一种可持续的方法。

我想要的是为子弹创建一个连接表。比如:

CREATE TABLE SomethingBullet (
  Id int NOT NULL PRIMARY KEY IDENTITY(1,1),
  Something_Id int NOT NULL,
  Resource_Id int NOT NULL
)

这样,当我将其他 20 多个实体添加到数据库中时,我最终不会得到一个非常宽且稀疏的 Resource 表。

如何指示 Automapper 以这种方式处理所有 IList&lt;Resource&gt; 属性?

【问题讨论】:

【参考方案1】:

:)

我发现使用自动映射进行这项工作的唯一方法是构建您自己的自定义自动映射步骤并替换“本机”HasManyToManyStep。恐怕是那个或覆盖。

我从Samer Abu Rabie, posted here 中取出了我的。

好消息是,到目前为止,Samer 的代码似乎与我的约定和诸如此类的东西完美配合,因此,一旦到位,它对我代码中的其他所有内容都是完全透明的。

坏消息是,单向的一对多关系会让您付出代价,因为 Samer 的代码假定 所有 x 对多的单向关系是多对多的。根据您的型号,这可能不是一件好事。

大概,您可以编写一个不同的 ShouldMap 实现,以区分您想要多对多和您想要一对多,然后一切都会再次工作。请注意,这将需要 两个 自定义步骤来替换本机 HasManyToManyStep,但同样,Samer 的代码是一个很好的起点。

让我们知道进展如何。 :)

干杯, J.

【讨论】:

【参考方案2】:

实际上,每个多对多都是由对象模型中的一对多组成的。如果您的关系不需要是双向的,则不要映射第二面。映射端的映射完全不受影响:

HasManyToMany(x => x.Bullets).AsSet();

在这种情况下,NHibernate 已经知道它需要生成中间表。

有关many-to-many 的提示,另请参阅本文。

【讨论】:

+1 - 查看链接博客,了解如何使用 FNH 和新的 NH 代码映射进行映射的优秀指导。

以上是关于Fluent NHibernate 自动映射:一对多实体,多对多后端?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Fluent NHibernate 中将一对一关系映射为复合键的一部分

使用自动映射时如何使用 Fluent NHibernate Validator?

如何使用 Fluent NHibernate 自动映射禁用特定抽象基类的子类化

Fluent NHibernate 多对多映射,使用自动生成的 pk 而不是复合键

自动增量(身份)在 Fluent NHibernate 中不起作用

Fluent Nhibernate Mapping - 值对象内的一对多?