2010-02-18 123 views
6

我们有一个多对多的集合映射为一个懒加载包的实体。当我们加载实体时,集合没有加载 - 非常好。现在我们要为该集合添加一个新的实体。只要我们这样做,收集就会加载。NHibernate:添加一个实体到一个懒加载的多对多关系

如何在不加载整个集合(集合很大)的情况下添加新实体?

回答

0

此行为的原因是当您向其添加()一个新项目时引用您的集合。该引用触发延迟加载。

我发现最好避免在NHibernate中显式的多对多映射。我通常使用两个一对多关联到第三个实体,其工作方式类似于链接表。确保将关系的许多方面设置为inverse =“true”。然后,您可以直接执行:

session.Save(new LinkEntity(leftSideInstanceOrProxy, rightSideInstanceOrProxy);

另一个好处是,通常有大约要保存的关系,这也可以去新实体的信息。

+1

当没有额外的信息需要时,这种方法使得你的域模型持久化依赖于 – Paco

+0

是的,我不想在这个模型中添加一个与业务无关的类。但是,我做了一个秒杀,而且我无法用其他方式做。我在想NHibernate不支持这个吗?如果是这样,有谁知道为什么不呢? – JontyMC

+0

二级缓存如何? – dariol

1

我有同样的问题。

您只需创建中间实体并执行两个一对多关系。

如果您检查了它生成的用于更新多对多关系的语句,则无论如何您都不会使用它。 当您将一个新项目添加到多对多关系中时,首先加载的关系(我认为这会生成一个select语句),然后更新该关系并进行提交。这种事情发生:

删除针对每一个对象在阵列中进行(也许这是一个delete语句或N DELETE语句,我不记得了)

所有对象都重新插入到数据库(N insert语句+新的那一个)。

如果您对多对多关系进行了大量更新,那么多对多映射不适合您。您可以在不更改或不经常更改的对象上使用多对多(因为所有删除和重新插入)。

您应该制作3个对象(比如说User,Post,Vote - 这是一个USER_POST中间表)。 为所有这些表创建主键(即使对于USER_POST)。创建一个代理键,并为USER_ID,POST_ID设置为USER_POST表的唯一约束。将它映射为普通的一对多,多对一(亲子,亲子)关系,就是这样。

1

如果您不想更改域模型,则可以直接执行SQL以更新m-m链接表(使用Nhibernate查询或执行参数化存储过程)。

此外,请注意,您将无法使用Add()操作(否则NH会自动触发延迟加载)。相反,请考虑在您的存储库类上调用一个适当命名的方法。

相关问题