Свободный NHibernate родительско-дочерний каскад SaveOrUpdate завершается ошибкой - PullRequest
2 голосов
/ 02 ноября 2010

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

Ниже приведены две таблицы SQL:

CREATE TABLE [dbo].[User]
(
    [Id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [Name] [varchar](50) NOT NULL,
)
CREATE TABLE [dbo].[Group]
(
    [Id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [GroupName] [varchar](50) NOT NULL,
    [UserId] [int] NOT NULL,
)

ALTER TABLE [dbo].[Group]  WITH CHECK ADD  CONSTRAINT [FK_Group_User] FOREIGN KEY([UserId])
REFERENCES [dbo].[User] ([Id])

Объекты представляютэти две таблицы со следующими сопоставлениями:

public class UserMap : ClassMap<User>
{
    public UserMap()
    {
        Table("[User]");
        Id(x => x.Id).GeneratedBy.Identity();
        Map(x => x.Name).Not.Nullable();
        HasMany(x => x.Groups).KeyColumn("UserId").Cascade.SaveUpdate();
    }
}

public class GroupMap : ClassMap<Group>
{
    public GroupMap()
    {
        Table("[Group]");
        Id(x => x.Id).GeneratedBy.Identity();
        Map(x => x.GroupName).Not.Nullable();
        References(x => x.User).Column("UserId").Not.Nullable();
    }
}

Код для создания объектов просто:

User u = new User () {Name = "test"};Группа g = новая группа () {GroupName = "Группа тестирования"};u.Groups.Add (g);

    using (var session = factory.OpenSession())
    {
        session.SaveOrUpdate(u);
    }

Однако происходит сбой за исключением «Невозможно вставить значение NULL в столбец« UserId », таблица« test.dbo.Group »; столбец не допускает пустых значений.INSERT завершается неудачно. Оператор завершен ".Я подозреваю, что это из-за того, что идентификатор родительского объекта (столбец идентификаторов) передается как NULL, а не новые значения.Это ошибка или есть способ исправить эти отображения так, чтобы это каскадное отношение было успешным?

Ответы [ 2 ]

4 голосов
/ 03 ноября 2010

У меня недавно был точный тип отображения, работающий нормально в проекте. Мой совет:

  • Узнайте, как работает атрибут Inverse отношения HasMany. Отличное объяснение здесь
  • Вам нужна двусторонняя связь между родительским и дочерним объектом. Это объясняется в нижней части статьи, на которую есть ссылка.

Еще один хороший совет - лучше инкапсулировать ваши коллекции. - Не обращайтесь напрямую к методам изменения ваших коллекций. Свойства коллекции должны быть доступны только для чтения, а родительский (класс пользователя в вашем случае) должен иметь методы AddGroup () и RemoveGroup (), которые изменяют частную коллекцию. Чтобы это работало, вы должны разрешить NHibernate доступ к члену частной коллекции с помощью .Access.CamelCaseField (Prefix.Underscore) или аналогичного атрибута отображения. Хорошая дискуссия об этом здесь

При необходимости я могу опубликовать пример сопоставления и файлы классов.

3 голосов
/ 02 ноября 2010

Сначала вам нужно сохранить пользователя, затем назначить группу пользователю и сохранить это:

using (var session = factory.OpenSession())
    {

User u = new User() { Name = "test"};
    session.SaveOrUpdate(u);

Group g = new Group() { GroupName = "Test Group", User = u };
session.SaveOrUpdate(g)


}

Я обнаружил, что вы не можете каскадно сохранять дочерние / родительские объекты, которые были только что созданы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...