Думаю, я бы тоже так поступил, но, думаю, немного «неуклюже» моделировать его так.
Я имею в виду: у вас есть набор людей, с которыми связан определенный человек, но у вас также есть «обратная связь».
Это действительно необходимо? Разве это не возможность удалить эту обратную коллекцию и вместо этого указать метод в PersonRepository, который может вернуть вам всех людей, имеющих какие-то отношения с данным человеком?
Хм, это может показаться немного неясным, так что вот некоторый код (обратите внимание, что для краткости я пропустил «виртуальные» модификаторы и т. Д. (Я также предпочитаю не иметь этих модификаторов, поэтому в 99% случаев я указываю 'lazy = false' в моем отображении классов).
public class Person
{
public int Id {get; set;}
public string Name {get; set;}
public IList<PersonPerson> _relatedPersons;
public ReadOnlyCollection<PersonPerson> RelatedPersons
{
get
{
// The RelatedPersons property is mapped with NHibernate, but
// using its backed field _relatedPersons (can be done using the
// access attrib in the HBM.
// I prefer to expose the collection itself as a readonlycollection
// to the client, so that RelatedPersons have to be added through
// the AddRelatedPerson method (and removed via a RemoveRelatedPerson method).
return new List<PersonPerson) (_relatedPersons).AsReadOnly();
}
}
public void AddRelatedPerson( Person p, RelationType relatesAs )
{
...
}
}
Как видите, у класса Person остается только одна коллекция, то есть коллекция объектов PersonPerson, представляющих отношения, которые имеет этот Person.
Чтобы получить людей, имеющих отношения с данным человеком, вы можете создать специальный метод в вашем PersonRepository, который возвращает эти люди, вместо того, чтобы помещать их в коллекцию класса Person. Я думаю, что это также улучшит производительность.
public class NHPersonRepository : IPersonRepository
{
...
public IList<Person> FindPersonsThatHaveARelationShipWithPerson( Person p )
{
ICriteria crit = _session.CreateCriteria <Person>();
crit.AddAlias ("RelatedPersons", "r");
crit.Add (Expression.Eq ("r.RelatedWithPerson", p));
return crit.List();
}
}
Обратная ссылка не является членом класса Person; к нему нужно получить доступ через репозиторий.
Это также то, что Эрик Эванс говорит в своей книге DDD: в некоторых случаях лучше иметь специализированный метод для хранилища, который может дать вам доступ к связанным объектам, вместо того, чтобы иметь их (= связанные объекты) для переноски. с самим объектом.
Я не тестировал код, я просто набрал его здесь, поэтому я также не проверял синтаксическую ошибку и т. Д. ... но я думаю, что это должно прояснить немного, как я это вижу.