NHibernate - как удалить элемент из отношения многие ко многим? - PullRequest
4 голосов
/ 16 февраля 2012

Я следую за отображением для двух таблиц, имеющих отношение «многие ко многим» между ними. Как удалить запись из таблицы сопоставления, в моем случае это «ProjectUser»?

public ProjectMap()
{
    Id(x => x.Id);
    Map(x => x.ProjectName);
    Map(x => x.Description);
    References<User>(x => x.Owner);
    HasManyToMany(x => x.Users)
        .Cascade.SaveUpdate()
        .Table("ProjectUser")
        .Not.LazyLoad();
}


public UserMap()
{
    Id(x => x.Id);
    Map(x => x.FirstName);
    Map(x => x.LastName);
    Map(x => x.UserName);
    HasManyToMany(x => x.Projects)
        .Cascade.SaveUpdate()
        .Inverse()
        .Table("ProjectUser")
        .Not.LazyLoad();
}

РЕДАКТИРОВАТЬ: изменил Каскад на SaveUpdate, как предложено в ответах. Вот код, который я использую для фиксации данных в базе данных SQLite.

using (var trans = session.BeginTransaction())
{
    var existingUsers = project.Users.ToList();
    foreach (var item in existingUsers)
    {
        if (selectedUsers.Count(x => x.Id == item.Id) == 0)
            project.Users.RemoveAt(project.Users.IndexOf(item));
    }
    session.SaveOrUpdate(project); // This fixed the issue
    session.Flush();
    foreach (var item in selectedUsers)
    {
        if (project.Users.Count(x => x.Id == item.Id) == 0)
        {
            project.AddUser(session.Get<User>(item.Id));
        }
    }
    session.SaveOrUpdate(project);
    session.Flush();
    trans.Commit();
}

// Add user code in Project class
public virtual void AddUser(User userToAdd)
{
    if (this.Users == null)
        this.Users = new List<User>();
    userToAdd.Projects.Add(this);
    this.Users.Add(userToAdd);
}

Всякий раз, когда я пытаюсь сохранить / обновить, я получаю следующую ошибку:

другой объект с тем же значением идентификатора уже был связан с сеансом: 10, объекта: Models.Project

EDIT2: следует использовать session.SaveOrUpdate (project) и session.Flush (), чтобы избежать ошибки, указанной выше.

Ответы [ 3 ]

7 голосов
/ 16 февраля 2012

Если вы хотите удалить только запись ProjectUser, а не удалить сущность на другой стороне, вам нужно изменить значение с Cascade.All() на Cascade.SaveUpdate().

В настоящее время, если вы удалили пользователя из проекта и сохранили проект, он удалил бы запись ProjectUser и объект User.

0 голосов
/ 16 февраля 2012

Если вы хотите удалить связь между Проектом и Пользователем (это означает удаление записи из объединяющей таблицы ProjectUser), вам следует действовать со стороны, не связанной со вселенной.В вашем случае это означает, что вы должны удалить сущность пользователя из коллекции «Пользователи проекта»:

project.Users.Remove(user);

По моему мнению, каскад в ассоциации «многие ко многим».должен быть установлен в SaveUpdate.Вы не хотите удалять проект при удалении пользователя.

0 голосов
/ 16 февраля 2012

Я полагаю, что нужно удалить соответствующий объект User из коллекции Project.Users и сохранить этот проект. Затем каскад удалит запись в «ProjectUser».

...