2

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 からリロードする必要なく、ドメイン モデルの整合性を維持できるはずだと思います。

更新: コメンターに触発されたコードの微調整。

4

4 に答える 4

3

そこにはドメインの概念が欠けている可能性があります。3 番目のエンティティー FooBarRelationship を作成してみましたか?

于 2008-11-22T19:49:10.107 に答える
2

Hibernate のドキュメントの双方向リンクの作業を参照してください。

多くの開発者は防御的にプログラミングし、リンク管理メソッドを作成して、両方の側を正しく設定します (例: Person):

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);
于 2008-11-22T19:38:27.600 に答える
1

あなたは一方が関係を「所有」すると言いました。このメソッドを公開します。他の関連付け (またはメソッドの追加) は、コンシューマーが直接操作するのを避けるために内部的に行うことができます。

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;}
}
于 2008-11-22T19:56:02.323 に答える
-1

あなたはそれを静的にすることができます

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
    }
}

あまり理想的ではありませんが、オブジェクト自体から関数を取得します

于 2008-11-22T19:35:03.223 に答える