2

我有两个实体 Foo 和 Bar,它们之间存在多对多关系。

假设对于为什么 Foo 可能对多对多关系“负责”没有语义论据,但是我们任意决定 Foo 负责该关系(即,在 NHibernate 中,我们将 Bar 标记为 Inverse)

从数据库的角度来看,这一切都很好,但是我的实体 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 中的关联集合?

我觉得我应该能够保持我的域模型的完整性,而不必在这样的操作之后从数据库中重新加载这些实体。

更新:受评论者启发的代码调整。

4

4 回答 4

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

我个人认为持有相关对象列表的实体对象太聪明了,你应该让 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 回答