【问题标题】:Why does NHibernate delete and recreate all associations in a collection when I add one item to it?为什么 NHibernate 在我向集合中添加一项时会删除并重新创建集合中的所有关联?
【发布时间】:2012-06-08 19:52:33
【问题描述】:

我正在使用 NHibernate 进行一些测试,我目前有两个映射实体,OrdersProducts。与往常一样,Order 包含 Products 集合,我将其映射为:

<bag name="Products" cascade="all" lazy="true">
  <key column ="Order_ID" />
  <many-to-many class="Product" column="Product_ID" />
</bag>

在 C# 方面:

public virtual IList<Product> Products
{
    get { return _Products; }
    set { _Products = value; }
}
private IList<Product> _Products = new List<Product>();

如果我在数据库中有一个持久的 Order(John 的订单),其 Products 集合中有一些项目(一个苹果、一个橙子和一个椰子)和我尝试向集合中添加一个新项目(香蕉),我可以从 SQL 输出中看到 NHibernate 正在执行以下操作:

INSERT INTO Products_Table (Product_Name, Product_ID) VALUES ('Banana', @Banana_ID)
DELETE FROM Products WHERE Order_ID = @Johns_Order_ID
INSERT INTO Products (Order_ID, Product_ID) VALUES (@Johns_Order_ID, @Apple_ID)
INSERT INTO Products (Order_ID, Product_ID) VALUES (@Johns_Order_ID, @Orange_ID)
INSERT INTO Products (Order_ID, Product_ID) VALUES (@Johns_Order_ID, @Coconut_ID)
INSERT INTO Products (Order_ID, Product_ID) VALUES (@Johns_Order_ID, @Banana_ID)

而不是简单地做这样的事情:

INSERT INTO Products_Table (Product_Name, Product_ID) VALUES ('Banana', @Banana_ID)
INSERT INTO Products (Order_ID, Product_ID) VALUES (@Johns_Order_ID, @Banana_ID)

那么,当我只想在其中插入新产品时,为什么 NHibernate 会从 Products 表中删除所有关联以重新创建它们?如何避免?

提前致谢!

PS:我尝试使用 SO Question 中建议的 inverse 映射属性,但即使新产品已保存其与订单的关联也没有。

编辑:

这是我用来修改产品列表的代码:

Order order = session.Load<Order>(orderId);
order.Products.Add(new Product() { Name = "Banana" });
using (ITransaction transaction = session.BeginTransaction())
{
    session.Update(order);
    transaction.Commit();
}

【问题讨论】:

  • 能否展示修改产品列表的代码
  • 您好,我编辑了我的问题,按照您的建议包含了我用来修改产品列表的代码。

标签: c# nhibernate nhibernate-mapping


【解决方案1】:

在 SO 上已经有一个类似的问题:NHibernate Many-To-Many Is Deleting All Associations Before Inserting

来自 NHibernate 的documentation

包是最坏的情况。由于袋子允许重复的元素值 并且没有索引列,不能定义主键。 NHibernate 有 无法区分重复的行。 NHibernate 解决了 通过完全删除(在单个 DELETE 中)和 每当它发生变化时重新创建集合。这可能非常 效率低下。

【讨论】:

  • 感谢您的回答,很抱歉自己无法找到类似的问题。现在我将我的映射切换到 idbag 而不是 bag 并且一切都像魅力一样工作!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-17
  • 2020-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多