APIで多対多のリレーションを処理する方法
-
10-07-2019 - |
質問
2つのエンティティFooとBarがあり、それらの間に多対多の関係があります。
Fooが「責任」となる理由についてのセマンティックな議論がないとしましょう。多対多の関係ではありますが、Fooが関係に責任があると任意に決定します(つまり、NHibernateでは、BarをInverseとしてマークします)
これはDBの観点からはすべて良好ですが、私のエンティティAPIは問題を明らかにしています。
// Responsible for the relation
public class Foo
{
List<Bar> Bars = new List<Bar>();
public void AddBar(Bar bar)
{
Bars.Add(bar);
bar.AddFoo(this);
}
}
public class Bar
{
List<Foo> Foos = new List<Foo>();
// This shouldn't exist.
public void AddFoo(Foo foo)
{
Foos.Add(foo);
foo.AddBar(this); // Inf Recursion
}
}
Fooがこの関係に責任があると判断した場合、存在しないはずのパブリックBar.AddFoo()メソッドを作成せずに、Barの関連コレクションを更新するにはどうすればよいですか?
このような操作の後、これらのエンティティをDBからリロードすることなく、ドメインモデルの整合性を維持できるはずだと思います。
更新:コメント作成者に触発されたコード調整。
解決
あなたは、片側が「所有する」と言いました。関係。このメソッドを公開します。他のアソシエーション(またはメソッドの追加)は、コンシューマーが直接対話することを避けるために内部的に作成できます。
public class Foo
{
private IList<Bar> Bars {get;set;}
public void AddBar(Bar bar)
{
Bars.Add(bar);
bar.Foos.Add(this);
}
}
public class Bar
{
internal IList<Foo> Foos {get;set;}
}
他のヒント
ドメインの概念が欠落している可能性があります。 3番目のエンティティFooBarRelationshipを作成しようとしましたか?
多くの開発者が防御的にプログラムします リンク管理方法を作成して 両側を正しく設定します。に 人:
protected Set getEvents() {
return events;
}
protected void setEvents(Set events) {
this.events = events;
}
public void addToEvent(Event event) {
this.getEvents().add(event);
event.getParticipants().add(this);
}
public void removeFromEvent(Event event) {
this.getEvents().remove(event);
event.getParticipants().remove(this);
}
個人的には、関連オブジェクトのリストを保持しているEntityオブジェクトはスマートすぎると思うので、DALにデータベースをヒットさせる必要があります。
DALFactory.FooAdapter.getBars(foo);
静的にすることができます
public class Foo
{
List<Bar> Bars = new List<Bar>();
public void AddBar(Bar bar)
{
Bars.Add(bar);
Bar.AddFoo(bar,this);
}
}
public class Bar
{
List<Foo> Foos = new List<Foo>();
// This shouldn't exist.
public static void AddFoo(Bar bar, Foo foo)
{
bar.Foos.Add(foo);
//foo.AddBar(this); inf recurtion
}
}
実際には理想的ではありませんが、オブジェクト自体から関数を取得します
所属していません StackOverflow