Fluent マッピングで NHibernate を使用していますが、多対多の関係に参加するとエントリが重複するという問題が発生します。以下の簡単な例には、PurchaseOrder と Product の 2 つのクラスがあります。PurchaseOrder は多くの製品を持つことができ、製品は多くの PurchaseOrder の一部になることができます。
PurchaseOrder とその製品を取得しようとすると、製品ごとに同じ PurchaseOrder が繰り返されます。(したがって、 PurchaseOrder に 5 つの製品がある場合、同じ PurchaseOrder が結果に 5 回表示されます。それぞれに 5 つの製品すべてが含まれます。)
これが私のセットアップです:
テーブル
PurchaseOrder
OrderID OrderDate
1 2013-01-01
2 2013-01-02
Product
ProductID Name
1 Widget
2 Thing
OrderProducts
OrderID ProductID
1 1
1 2
2 1
2 2
クラス
public class PurchaseOrder
{
public virtual int OrderID { get; set; }
public virtual DateTime? OrderDate { get; set; }
public virtual IList<Product> Products { get; set; }
}
public class Product
{
public virtual int ProductID { get; set; }
public virtual string Name { get; set; }
public virtual IList<PurchaseOrder> Orders { get; set; }
}
マッピング
public class PurchaseOrderMapping : ClassMap<PurchaseOrder>
{
public PurchaseOrderMapping()
{
Id(x => x.OrderID, "OrderID");
Map(x => x.OrderDate, "OrderDate");
HasManyToMany(x => x.Products)
.Table("OrderProducts")
.Schema("dbo")
.ParentKeyColumn("OrderID")
.ChildKeyColumn("ProductID");
Schema("dbo");
Table("PurchaseOrder");
}
}
public class ProductMapping : ClassMap<Product>
{
public ProductMapping ()
{
Id(x => x.ProductID, "ProductID");
Map(x => x.Name, "Name");
HasManyToMany(x => x.Orders)
.Table("OrderProducts")
.Schema("dbo")
.ParentKeyColumn("OrderID")
.ChildKeyColumn("ProductID")
.Inverse();
Schema("dbo");
Table("Product");
}
}
クエリオーバー
var orderList = session.QueryOver<PurchaseOrder>()
.JoinQueryOver<Product>(o => o.Products)
.List();
orderList には 2 つの PurchaseOrders があるはずですが、実際には 4 あります。OrderID=1 に対応するオブジェクトが繰り返され、OrderID=2 も同様です。
foreach(var o in orderList) { Console.WriteLine(o.OrderID); }
Output:
1
1
2
2
さらに言えば、同じ ID のオブジェクトを比較すると、それらは同じオブジェクトです。
System.Console.WriteLine(Object.ReferenceEquals(orderList[0], orderList[1]));
System.Console.WriteLine(Object.ReferenceEquals(orderList[2], orderList[3]));
Output:
True
True
NHibernate が結果のオブジェクトを複製するのはなぜですか? それらを除外して、それぞれに対応する 2 つの製品を含む 2 つの注文のリストを取得するにはどうすればよいですか?