7

NHibernate を使用していくつかのテストを行っており、現在、OrdersProductsの 2 つのエンティティがマップされています。いつものように、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>();

データベースに1 つの永続的な注文(John の注文) があり、Productsコレクション (リンゴ、オレンジ、ココナッツ) にいくつかのアイテムがあり、コレクション (バナナ) に新しいアイテムを追加しようとすると、 NHibernate が次のようなことを行っていることを示す SQL 出力から:

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 が製品テーブルからすべての関連付けを削除して再作成するのはなぜですか? それを避ける方法は?

前もって感謝します!

PS: このSO Questionで提案されているように、マッピング属性を使用しようとしましたが、新しい製品が保存されても、注文との関連付けは保存されません。

編集:

製品リストを変更するために使用しているコードは次のとおりです。

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

1 に答える 1

5

SOについては、すでに同様の質問があります。NHibernateの多対多は、挿入する前にすべての関連付けを削除しています。

NHibernateのドキュメントから:

バッグは最悪のケースです。バッグは要素値の重複を許可し、インデックス列がないため、主キーを定義することはできません。NHibernateには、重複する行を区別する方法がありません。NHibernateは、コレクションを完全に削除し(1回のDELETEで)、コレクションが変更されるたびに再作成することで、この問題を解決します。これは非常に非効率的かもしれません。

于 2012-06-08T21:14:05.153 に答える