Сущности: Команда ‹-> Сотрудник команды ‹-> Сотрудник
Требования:
- Команда и Сотрудник могут существовать без своего двойника.
- В отношении Team-TeamEmployee ответственна команда (родительская) [используя позже TeamRepository].
- В отношении Employee-TeamEmployee сотрудник является ответственным (родительским) [используя позже EmployeeRepository].
- Дубликаты не допускаются.
- Удаление Команды удаляет всех Сотрудников в Команде, если Сотрудник не входит в другую Команду.
- При удалении Сотрудника удаляется только Команда, если Команда больше не содержит Сотрудников.
Отображение:
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();
}
}
Создание сотрудников и команд:
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);
После этого я фиксирую изменения с помощью transaction.Commit (). Первая странность заключается в том, что мне нужно сохранить команды и сотрудников вместо одного из них (почему ?!). Если я сохраню только все команды или (Xor) всех сотрудников, я получу TransientObjectException:
"объект ссылается на несохраненный временный экземпляр - сохраните временный экземпляр перед сбросом. Тип: Core.Domain.Model.Employee, Entity: Core.Domain.Model.Employee"
Когда я сохраняю все созданные команды и сотрудников, все сохраняется нормально, НО в таблице отношений TeamEmployee есть повторяющиеся ассоциации.
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
Таким образом, вместо 4 отношений получается 8 отношений. 4 отношения для левой стороны и 4 отношения для правой стороны. : [
Что я не так?
Дополнительные вопросы: когда я удаляю команду или сотрудника, мне нужно удалить команду или сотрудника из списка TeamEmployee в объектной модели, или NHibernate выполняет эту работу за меня (используя session.delete (..))?