Fluent NHibernate 多対多
-
01-07-2019 - |
質問
Fluent NHibernate を使用していますが、クラスの 1 つと多対多の関係をセットアップする際に問題が発生しています。おそらく愚かな間違いですが、それを機能させるために少しの間立ち往生しました。とにかく、多対多の関係を持つクラスがいくつかあります。
public class Person
{
public Person()
{
GroupsOwned = new List<Groups>();
}
public virtual IList<Groups> GroupsOwned { get; set; }
}
public class Groups
{
public Groups()
{
Admins= new List<Person>();
}
public virtual IList<Person> Admins{ get; set; }
}
マッピングは次のようになります
人:...
HasManyToMany<Groups>(x => x.GroupsOwned)
.WithTableName("GroupAdministrators")
.WithParentKeyColumn("PersonID")
.WithChildKeyColumn("GroupID")
.Cascade.SaveUpdate();
グループ:...
HasManyToMany<Person>(x => x.Admins)
.WithTableName("GroupAdministrators")
.WithParentKeyColumn("GroupID")
.WithChildKeyColumn("PersonID")
.Cascade.SaveUpdate();
統合テストを実行するときは、基本的に新しい個人とグループを作成します。グループを Person.GroupsOwned に追加します。リポジトリから Person オブジェクトを取得すると、GroupsOwned は最初のグループと等しくなりますが、グループを取得したときに Group.Admins のカウントを確認すると、カウントは 0 になります。Join テーブルには、GroupID と PersonID が保存されています。
アドバイスをありがとうございます。
解決
テーブルに 2 つのレコードが追加されているという事実は、 逆属性. 。個人とグループの両方が変更されるため、Hibernate は関係を 2 回 (オブジェクトごとに 1 回) 永続化します。inverse 属性は、特にこれを回避するためのものです。
コード内のマッピングに追加する方法はわかりませんが、リンクには XML で追加する方法が示されています。
他のヒント
@Santiagoあなたの言う通りだと思います。
答えは、ManyToMany 宣言の 1 つを削除する必要があるということかもしれません。Fluent を詳しく見ると、それを自動的に実行するのに十分賢いように見えます。
人物を Groups.Admin に追加しますか?両方のリンクを作成する必要があります。
テーブルが3つありますよね?
ユーザー、グループ、およびグループ管理者
両辺を加算すると、次のようになります
人々(P1のIDを含む)グループ(G1のIDを含む)
GroupAdministrators には 2 つの列と 1 つのテーブルがあります。
(p1,g1)
(p1,g1)
単体テストのコードは次のようになります。
Context hibContext //Built here
Transaction hibTrans //build and start the transaction.
Person p1 = new Person()
Groups g1 = new Groups()
p1.getGroupsOwned().add(g1)
g1.getAdmins().add(p1)
hibTrans.commit();
hibContext.close();
そして、テストで新しいコンテキストを作成し、そのコンテキストに何が含まれているかをテストすると、正しい結果が返されますが、テーブルがすべてめちゃくちゃになっていませんか?