NHibernate - Come eliminare un elemento da molti-a-molti?
Domanda
Ho seguito la mappatura per due tabelle che hanno una relazione molti-a-molti tra di loro. Come faccio a cancellare una voce dalla tabella di mappatura, che è 'ProjectUser' nel mio caso?
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();
}
EDIT: cambiato Cascade per SaveUpdate come suggerito nelle risposte. Ecco il codice che uso per commettere i dati di database 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);
}
Ogni volta che provo a salvare / aggiornare sto ottenendo il seguente errore:
un oggetto diverso con lo stesso valore identificativo è già stato associato alla sessione: 10, di entità: Models.Project
EDIT2:. Dovranno utilizzare Session.saveOrUpdate (progetto) e Session.flush () per evitare di errore indicato in precedenza
Soluzione
Se si desidera solo rimuovere la voce ProjectUser e non effettivamente eliminare l'entità dall'altra parte è necessario modificare da Cascade.All()
a Cascade.SaveUpdate()
.
Al momento, se si rimuove un utente da un progetto e salvato il progetto sarebbe eliminare la voce ProjectUser
e l'oggetto User
.
Altri suggerimenti
La mia ipotesi sarebbe quello di eliminare l'entità utente appropriato dalla raccolta Project.Users e salvare quel progetto. La cascata sarebbe quindi rimuovere la voce in "ProjectUser".
Se si desidera rimuovere collegamento tra un progetto e di un utente (che significa la rimozione di record dalla join tavolo ProjectUser) si dovrebbe agire da un lato noniverse. Nel tuo caso significa che si dovrebbe rimuovere entità utente da collezione utenti del progetto:
project.Users.Remove(user);
A mio parere a cascata in molti-a-molti assoc. deve essere impostato su SaveUpdate. Se non si desidera eliminare il progetto quando l'utente viene eliminato.