我的目标是使用NHibernate模式生成以及Fluent NHibernate的automapper来生成我的数据库。我遇到了我称之为“单向多对多关系”的问题。
我的许多实体都有本地化资源。单个类可能如下所示:
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<Resource>
,则会按照我的意愿生成所有内容 - 资源ID位于Title
和Description
字段中。当我添加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
)
这样,当我将其他二十多个实体添加到数据库中时,我不会得到一个可笑的宽且稀疏的Resource
表。
如何指示Automapper以这种方式处理所有IList<Resource>
属性?
答案 0 :(得分:4)
事实上,每对多对多都是由对象模型中的一对多组成。如果你的关系不需要是双向的,那就不要映射第二面。映射端的映射完全不受影响:
HasManyToMany(x => x.Bullets).AsSet();
在这种情况下,NHibernate已经知道它需要生成中间表。
另请参阅本文了解many-to-many提示。
答案 1 :(得分:0)
:)
我发现通过自动化实现此功能的唯一方法是构建您自己的自定义自动化步骤并替换“原生”HasManyToManyStep。它是要么是超越,要害我。
我把我从Samer Abu Rabie, posted here抬起来。
好消息是,到目前为止,Samer的代码似乎与我的约定和诸如此类的东西完美配合,因此,一旦它到位,它对我代码中的其他内容完全透明。
坏消息是,您需要具备单向一对多关系的能力,因为Samer的代码假定所有 x-to-many单向关系是多对多关系。根据您的型号,这可能是也可能不是一件好事。
据推测,您可以编写一个不同的ShouldMap实现,它可以区分您想要多对多的内容以及您希望成为一对多的内容,然后一切都会再次运行。请注意,这需要两个自定义步骤来替换本机HasManyToManyStep,尽管Samer的代码是一个很好的起点。
让我们知道它是怎么回事。 :)
干杯,
学家