Биди-ассоциации и картография NHibernate - PullRequest
1 голос
/ 12 октября 2008

У меня есть классы BidiParent и BidiChildList, которые связывают родителей и детей в двунаправленных отношениях родитель-ребенок. Если родитель ребенка обновляется, например, сервисный слой, старые и новые дочерние списки родителей автоматически обновляются для отражения изменений. Аналогично, если список детей родителей обновляется, например, При добавлении нового дочернего элемента родительский элемент автоматически изменяется, как и список дочерних элементов старого родительского элемента. Я хочу попытаться создать «умную» модель домена.

Первый вопрос, очевидно, таков: это даже хорошая идея?

Второй вопрос: можно ли указать NHibernate для доступа и изменения поля _Children или _Parent, но считать свойство Children или Parent полностью синонимичным с полем ? Что NHibernate должен загружать и сохранять внутренние поля, но запросы HQL или LINQ должны использовать открытые свойства?

public class BidiParent<C, P> { ... }

public class BidiChildList<C, P> : IList<C> { ... }

public class Parent {
    public string Name { get; set; }
    public IList<Child> Children {
        get { return ChildrenBidi; }
        set { ChildrenBidi.Set(value); }
    }
    private BidiChildList<Child, Parent> ChildrenBidi {
        get { return BidiChildList.Create(this, p => p._Children, c => c._Parent, (c, p) => c._Parent = p); }
    }
    internal IList<Child> _Children = new List<Child>();
}

public class Child {
    public string Name { get; set; }
    public Parent Parent {
        get { return ParentBidi.Get(); }
        set { ParentBidi.Set(value); }
    }
    private BidiParent<Child, Parent> ParentBidi {
        get { return BidiParent.Create(this, p => p._Children, () => _Parent, p => _Parent = p); }
    }
    internal Parent _Parent = null;
}

[Test]
public void MultilevelConstruction_Succeeds() {
    var p = new Parent {
        Name = "Bob",
        Children = new List<Child> {
            new Child { Name = "Kate" },
            new Child { Name = "Billy" }
        }
    };
    Assert.AreEqual(2, p.Children.Count);
    Assert.AreEqual("Kate", p.Children[0].Name);
    Assert.AreEqual("Billy", p.Children[1].Name);
    Assert.AreSame(p, p.Children[0].Parent);
    Assert.AreSame(p, p.Children[1].Parent);
}

1 Ответ

1 голос
/ 13 октября 2008

Отвечая на мой собственный вопрос: мне нужно использовать стратегию именования, как описано в документах . RTFM верно?

<class name="Parent">
    <property name="Name" />
    <bag name="Children" access="field.pascalcase-underscore">
        <key />
        <one-to-many class="Child" />
    </bag>
</class>
<class name="Child">
    <property name="Name" />
    <many-to-one name="Parent" access="field.pascalcase-underscore" />
</class>
...