使用关联类实现双向、多对多关联的流畅 NHibernate 映射

发布于 2024-11-08 18:17:54 字数 1532 浏览 0 评论 0原文

我在 EntityA 和 EntityB 之间有一个双向多对多关联,并且我使用关联类 EntityABLink 对此进行建模,因为我需要跟踪有关该关系的其他属性。此外,我还有另一个类,它保存对 EntityA 和 EntityB 之间特定关系的引用,因此我将关联类视为成熟的实体。

在 EntityA 中,我有一个只读属性,它返回关联的 EntityB 对象的列表,同样,在 EntityB 中,我有一个只读属性,它返回关联的 EntityA 对象的列表。请注意,对于这些属性,我隐藏了关联是通过关联类实现的事实。 (我还有专门的方法来更新隐藏实现的关系。)在 EntityA 和 EntityB 的幕后,我有 EntityABLink 类型的私有集合。

由于一张图片胜过一千个文字,因此我到目前为止所描述的内容如下:
在此处输入图像描述

(再次注意,EntityA 和 EntityB 上的公共只读属性与 EntityA 和 EntityB 的类型不同支持他们的私人成员。)

到目前为止,一切顺利。现在我想使用 Fluent NHibernate 自动映射覆盖将这些对象持久保存到数据库中。当谈到映射时,我喜欢使用这种功能等效的表示来考虑上述内容:
在此处输入图像描述 从该图中可以清楚地看出,我真正需要的是两个双向一对多关系。

在映射上面的内容时,我认为我需要这样的东西:

在 EntityA 自动映射覆盖中:

mapping.HasMany<EntityABLink>(Reveal.Member<EntityA>(“_AssociationList”)).Inverse().AsBag().Cascade.SaveUpdate(); 
mapping.IgnoreProperty(x => x.EntityBList);

在 EntityB 自动映射覆盖中:

mapping.HasMany<EntityABLink>(Reveal.Member<EntityB>(“_AssociationList”)).Inverse().AsBag().Cascade.SaveUpdate(); 
mapping.IgnoreProperty(x => x.EntityAList);

在 EntityABLink 自动映射覆盖中:

mapping.References<EntityA>(x => x.EntityA).Not.Nullable();
mapping.References<EntityB>(x => x.EntityB).Not.Nullable();

但是,当我尝试此操作时,我收到以下错误:

“无法找到类“EntityB”中属性“_ AssociationList”的 getter。”

我的映射一定有问题,但我不确定是什么。有什么想法吗?

I have a bi-directional, many-to-many association between EntityA and EntityB and I’m using an association class, EntityABLink, to model this because there are other attributes about the relationship that I need to track. In addition, I also have another class that holds a reference to a specific relationship between EntityA and EntityB so I treat the association class as a full-fledged entity.

In EntityA I have a read-only property that returns a list of associated EntityB objects and, likewise, in EntityB I have a read-only property that returns a list of associated EntityA objects. Note that, for these properties, I’m hiding the fact that the association is implemented via an association class. (I also have dedicated methods for updating the relationships that hide the implementation.) Behind the scenes in both EntityA and EntityB, I have private collections of type EntityABLink.

Since a picture is worth a thousand words, here is what I have described so far:
enter image description here

(Note again that the public, read-only properties on EntityA and EntityB are not of the same type as the private members that back them up.)

So far, so good. Now I want to persist these objects to a database using Fluent NHibernate automapping overrides. When it comes to mapping, I like to think of the above using this functionally equivalent representation:
enter image description here
From this diagram, it’s clear that what I really need is two bi-directional one-to-many relationships.

In mapping the above, I figure that I need something like this:

In the EntityA automapping override:

mapping.HasMany<EntityABLink>(Reveal.Member<EntityA>(“_AssociationList”)).Inverse().AsBag().Cascade.SaveUpdate(); 
mapping.IgnoreProperty(x => x.EntityBList);

In the EntityB automapping override:

mapping.HasMany<EntityABLink>(Reveal.Member<EntityB>(“_AssociationList”)).Inverse().AsBag().Cascade.SaveUpdate(); 
mapping.IgnoreProperty(x => x.EntityAList);

In the EntityABLink automapping override:

mapping.References<EntityA>(x => x.EntityA).Not.Nullable();
mapping.References<EntityB>(x => x.EntityB).Not.Nullable();

When I try this, however, I get the following error:

"Could not find a getter for property '_ AssociationList’ in class 'EntityB'."

I must have something wrong with my mappings, but I’m not sure what. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

泪之魂 2024-11-15 18:17:54

我现在已经可以使用了。所以这就是技巧......我恢复到 Fluent NHibernate 版本 1.1(特别是 1.1.0.685)。然后,尽管使用“Reveal.Member”的映射示例并未显示它是必要的,但我将“Access.Field()”添加到了 EntityA._AssociationList 和 EntityB._AssociationList 的映射中。这是工作映射。

在 EntityA 自动映射覆盖中:

mapping.HasMany<EntityABLink>(Reveal.Member<EntityA>(“_AssociationList”)).Inverse().AsBag().Cascade.SaveUpdate().Access.Field(); 
mapping.IgnoreProperty(x => x.EntityBList);

在 EntityB 自动映射覆盖中:

mapping.HasMany<EntityABLink>(Reveal.Member<EntityB>(“_AssociationList”)).Inverse().AsBag().Cascade.SaveUpdate().Access.Field(); 
mapping.IgnoreProperty(x => x.EntityAList);

在 EntityABLink 自动映射覆盖中:

mapping.References<EntityA>(x => x.EntityA).Not.Nullable();
mapping.References<EntityB>(x => x.EntityB).Not.Nullable();

在 FNH 1.1 中工作后,我尝试升级到 FNH 1.2。 不好。我尝试了 1.2.0.694 以及 1.2.0.712,这两个仍然给出了错误的错误消息,指出不同的“实体”(实际上是一个枚举) !) 没有映射 Id。

Fluent NHibernate 是一个很棒的工具,所以我希望最新版本中的错误能够得到修复。 :-)

I got it working now. So here's the trick... I reverted back to Fluent NHibernate version 1.1 (specifically 1.1.0.685). Then, although the mapping examples that use "Reveal.Member" don't show it as being necessary, I added "Access.Field()" to the mapping for both EntityA._AssociationList and EntityB._AssociationList. Here are the working mappings.

In the EntityA automapping override:

mapping.HasMany<EntityABLink>(Reveal.Member<EntityA>(“_AssociationList”)).Inverse().AsBag().Cascade.SaveUpdate().Access.Field(); 
mapping.IgnoreProperty(x => x.EntityBList);

In the EntityB automapping override:

mapping.HasMany<EntityABLink>(Reveal.Member<EntityB>(“_AssociationList”)).Inverse().AsBag().Cascade.SaveUpdate().Access.Field(); 
mapping.IgnoreProperty(x => x.EntityAList);

In the EntityABLink automapping override:

mapping.References<EntityA>(x => x.EntityA).Not.Nullable();
mapping.References<EntityB>(x => x.EntityB).Not.Nullable();

Once it was working in FNH 1.1, I tried upgrading to FNH 1.2. No good. I tried 1.2.0.694 as well as 1.2.0.712 and both of these still give the incorrect error message that a different "entity" (which is actually an enum!) doesn't have an Id mapped.

Fluent NHibernate is a wonderful tool so I hope that the bug in the latest version gets fixed. :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文