NHibernate wiele do wielu powiązań, które kończą się jako rodzic za pomocą jednostki relacji w Modelu Domeny
Podmioty: Zespół <-> TeamEmployee <-> Pracownik
Wymagania:
Zespół i pracownik mogą istnieć bez swojego odpowiednika.W relacji Team-TeamEmployee zespół jest odpowiedzialny (rodzic) [używając późniejszego TeamRepository].W relacji Pracownik-TeamEmployee pracownik jest odpowiedzialny (rodzic) [używając późniejszego repozytorium pracownika].Duplikaty nie są dozwolone.Usunięcie zespołu powoduje usunięcie wszystkich pracowników w zespole, jeśli pracownik nie znajduje się w innym zespole.Usunięcie pracownika powoduje usunięcie tylko zespołu, jeśli zespół nie zawiera więcej pracowników.Mapowanie:
public class TeamMap : ClassMap<Team>
{
public TeamMap()
{
// identity mapping
Id(p => p.Id)
.Column("TeamID")
.GeneratedBy.Identity();
// column mapping
Map(p => p.Name);
// associations
HasMany(p => p.TeamEmployees)
.KeyColumn("TeamID")
.Inverse()
.Cascade.SaveUpdate()
.AsSet()
.LazyLoad();
}
}
public class EmployeeMap : ClassMap<Employee>
{
public EmployeeMap()
{
// identifier mapping
Id(p => p.Id)
.Column("EmployeeID")
.GeneratedBy.Identity();
// column mapping
Map(p => p.EMail);
Map(p => p.LastName);
Map(p => p.FirstName);
// associations
HasMany(p => p.TeamEmployees)
.Inverse()
.Cascade.SaveUpdate()
.KeyColumn("EmployeeID")
.AsSet()
.LazyLoad();
HasMany(p => p.LoanedItems)
.Cascade.SaveUpdate()
.LazyLoad()
.KeyColumn("EmployeeID");
}
}
public class TeamEmployeeMap : ClassMap<TeamEmployee>
{
public TeamEmployeeMap()
{
Id(p => p.Id);
References(p => p.Employee)
.Column("EmployeeID")
.LazyLoad();
References(p => p.Team)
.Column("TeamID")
.LazyLoad();
}
}
Tworzenie pracowników i zespołów:
var employee1 = new Employee { EMail = "Mail", FirstName = "Firstname", LastName = "Lastname" };
var team1 = new Team { Name = "Team1" };
var team2 = new Team { Name = "Team2" };
employee1.AddTeam(team1);
employee1.AddTeam(team2);
var employee2 = new Employee { EMail = "Mail2", FirstName = "Firstname2", LastName = "Lastname2" };
var team3 = new Team { Name = "Team3" };
employee2.AddTeam(team3);
employee2.AddTeam(team1);
team1.AddEmployee(employee1);
team1.AddEmployee(employee2);
team2.AddEmployee(employee1);
team3.AddEmployee(employee2);
session.SaveOrUpdate(team1);
session.SaveOrUpdate(team2);
session.SaveOrUpdate(team3);
session.SaveOrUpdate(employee1);
session.SaveOrUpdate(employee2);
Następnie zatwierdzam zmiany za pomocą transaction.Commit (). Pierwszą dziwną rzeczą jest to, że muszę zapisać Zespoły i Pracowników zamiast jednego z nich (dlaczego ?!). Jeśli tylko uratuję wszystkie drużyny lub (Xor) wszystkich pracowników, otrzymamTransientObjectException:
„obiekt odwołuje się do niezapisanej instancji przejściowej - zapisz instancję przejściową przed opróżnieniem. Typ: Core.Domain.Model.Employee, Entity: Core.Domain.Model.Employee”
Kiedy zapisuję wszystkie utworzone zespoły i pracowników, wszystko zapisuje się dobrze, ALE tabela relacji ma TeamEmployeeduplikaty wniosków.
ID EID TID
1 1 1
2 2 1
3 1 2
4 2 3
5 1 1
6 1 2
7 2 3
8 2 1
Tak więc zamiast 4 relacji istnieje 8 relacji. 4 relacje po lewej stronie i 4 relacje po prawej stronie. : [
Co się mylę
Dalsze pytania: Czy po usunięciu zespołu lub pracownika muszę usunąć zespół lub pracownika z listy TeamEmployee w modelu obiektowym lub czy NHibernate wykona zadanie dla mnie (używając session.delete (..))?