Ich habe zwei Klassen, Benutzer- und Rollen, definiert als:NHibvernate 3.2 viele zu viele bevölkern nicht Tisch beitreten
public class User : Entity
{
// other properties ...
public virtual string Username
public virtual ICollection<Role> Roles { get; set; }
}
public class Role : Entity
{
public virtual string Name { get; set; }
public virtual ICollection<User> Users { get; set; }
}
In meinem Mapping-Code, habe ich die folgenden:
mapper.Class<User>(map =>
{
map.Bag(x=>x.Roles,
cm=>
{
cm.Table("UserRole");
cm.Cascade(Cascade.All);
cm.Key(k => k.Column("[User]"));
},
em=>
{
em.ManyToMany(mm =>
{
mm.Column("[Role]");
});
});
});
mapper.Class<Role>(map =>
{
map.Bag(x=>x.Users,
cm=>
{
cm.Inverse(true);
cm.Table("UserRole");
cm.Key(k=>k.Column("[Role]"));
},
em =>
{
em.ManyToMany(mm =>
{
mm.Column("[User]");
});
});
});
Die Zuordnungen Generieren Sie das erwartete Schema, aber die Join-Tabelle wird nie ausgefüllt. Das Hinzufügen eines neuen Benutzers mit einer neuen Rolle in seiner Sammlung behält die Rolle und dann den Benutzer für die entsprechenden Tabellen bei, aber die Join-Tabelle bleibt leer. Warum?
Edit: Ich habe noch keinen Fortschritt in diesem Bereich gemacht. Ich bin absolut sicher, dass das Mapping korrekt ist und das korrekte Schema generiert wird, aber die Join-Tabelle ist einfach nicht gefüllt. Zu Testzwecken mir generierenden Einheiten NBuilder mit etwa so:
var roles = new Role[]
{
new Role("Admin"),
new Role("Manager"),
new Role("User")
};
var users = Builder<User>.CreateListOfSize(10)
.TheFirst(1)
.Do(x =>
{
x.Roles.Add(roles[0]);
x.Roles.Add(roles[1]);
roles[0].Users.Add(x);
roles[1].Users.Add(x);
})
.All()
.With(x => x.Id = 0)
.And(x => x.Version = 0)
.And(x => x.Username = "test user")
.And(x => x.Password = "test password")
.Do(x =>
{
x.Roles.Add(roles[2]);
roles[2].Users.Add(x);
}
.Build();
foreach (var u in users) session.Save(u);
Die Benutzer- und Rolleneinheiten korrekt beibehalten werden, aber die Join-Tabelle bleibt leer. Das bedeutet, dass ich die Rollen für einen bestimmten Benutzer später nicht effektiv abfragen kann, wodurch der Punkt ungültig wird.
Großartig, dass Sie das herausgefunden haben! –
Auch ich denke, dass Sitzung.Flush(); Nach dem Speichern sollte auch funktionieren (ohne explizite Transaktion). Benutzer und Rolle werden ohne Notwendigkeit einer Transaktion gespeichert, da NH eine Rückmeldung von der Datenbank erhalten muss (wie automatisch generierte IDs), nachdem NH Datensätze in der Kreuztabelle speichern kann. –
Versuchen Sie nicht, dieses Verhalten zu umgehen, indem Sie Flush verwenden. nhibernate wurde entwickelt, um explizite Transformationen zu verwenden, also möchten Sie das akzeptieren. Siehe z.B. Die NHProf Dokumentation: http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions –