我们有一个多对多集合的实体映射为一个延迟加载的包。当我们加载实体时,集合未加载 - 很棒。现在我们要为该集合添加一个新实体。一旦我们这样做,集合就会被加载。
如何在不加载整个集合的情况下添加新实体(集合很大)?
答案 0 :(得分:1)
我遇到了同样的问题。
您只需创建中间实体并执行两个一对多关系。
如果您检查了它生成的语句以更新多对多关系,则无论如何都不会使用它。 当您将新项添加到多对多关系时,首先加载关系(我认为这会生成一个select语句),然后更新该关系并执行提交。这件事发生了:
对数组中的每个对象执行删除(可能是一个删除语句或N个删除语句,我不记得了)
将所有对象重新插入数据库(N insert语句+新语句)。
如果您对多对多关系进行了大量更新,那么多对多映射不适合您。您可以在不更改或不经常更改的对象上使用多对多(因为所有删除和重新插入)。
你应该制作3个对象(比方说User,Post,Vote - 这是一个USER_POST中间表)。 为所有这些表创建主键(即使对于USER_POST)。创建一个代理键,并为USER_ID制定一个约束,POST_ID对于USER_POST表是唯一的。将其映射为正常的一对多,多对一(父子,子父)关系,就是这样。
答案 1 :(得分:1)
如果您不想更改域模型,可以直接执行SQL来更新m-m链接表(使用Nhibernate查询或执行参数化存储过程)。
另外,请注意,您将无法使用Add()
操作(否则NH将自动触发延迟加载)。相反,请考虑在 Repository 类上调用一个适当命名的方法。
答案 2 :(得分:0)
此行为的原因是,当您向其添加()新项目时,您将引用您的集合。此引用会触发延迟加载。
我发现最好避免在NHibernate中显式的多对多映射。我通常使用两个一对多关联到第三个实体,它像链接表一样工作。确保将关系的多个边设置为inverse =“true”。然后,您可以直接执行:
session.Save(new LinkEntity(leftSideInstanceOrProxy, rightSideInstanceOrProxy);
另一个好处是,通常有关于您想要保存的关系的信息,这些信息也可以放在新实体中。