NHibernate каскад и генерируемые идентификаторы guid - почему они не генерируются для детей при сохранении? - PullRequest
0 голосов
/ 09 февраля 2010

Я делаю следующее:

    var @case = new Case
    {
        Name = "test"
    };

    // User is persistent and loaded in the same session
    User.AddCase(@case); // sets @case.User = User too
    Session.Update(User);

    response.CaseId = @case.Id;

Каскад на User.Cases установлен на Все. Но @ case.Id не устанавливается, пока транзакция не будет зафиксирована. Это ожидаемое поведение? Я бы очень хотел получить Id до совершения. Можно ли это сделать?

Ответы [ 2 ]

1 голос
/ 17 марта 2010

Более чистой DDD'y, вероятно, было бы, вероятно, моделировать User и Case как агрегированные корни, а затем моделировать их отношения с объектом роли RelatedCase (который агрегируется внутри User и поэтому должен быть каскад = "все-удалить-сирота").

Совокупные корни должны быть сохранены в репозиториях, которые (если вы делегируете вызов session.Save(...)) дадут вам нужный идентификатор в то время, когда вы можете его использовать.

Тогда роль может (и по моему опыту часто будет, по крайней мере, через какое-то время) содержать дополнительную информацию, которая характеризует отношения, и не принадлежит ни пользователю, ни делу. Допустим, отношения отслеживают, почему пользователь и дело связаны.

Так ваш код может выглядеть так:

var case = caseFactory.Create("name");
caseRepository.Save(case);

user.AssignCase(case, "Assigned by some dude");

- и внутри AddCase:

public void AddCase(Case case, string reason)
{
    cases.Add(new RelatedCase(case, reason));
}

Это, на мой взгляд, самый красивый способ моделировать подобные вещи, но вы, конечно, будете немного наказаны с точки зрения производительности. Если для вас важнее симпатичная модель, то вам стоит заняться чем-то вроде этого.

0 голосов
/ 13 февраля 2010

вы пробовали Session.SaveOrUpdate(User)? Хотя я должен сказать, что каскадные операции не выполняются до тех пор, пока они не потребуются, и это происходит при сбросе / фиксации. когда вы Session.Save(@case) вы не делаете сброс / коммит

Сказав, что вы совершаете логическую ошибку: создавая @case, вы не обновляете пользователя. Пользователь является отдельным объектом, и Case имеет внешний ключ для Пользователя. Таким образом, сохранение дела является правильным, а список дел пользователя является просто информацией об ассоциации

...