NHibernar asociaciones de muchos a muchos que hacen ambos extremos como padre utilizando una entidad de relación en el Modelo de dominio

Entidades: Team <-> TeamEmployee <-> Employee

Requisitos:

Un Equipo y un Empleado pueden existir sin su contraparte.En la relación Team-TeamEmployee el equipo es responsable (padre) [usando más tarde un TeamRepository].En la relación Empleado-EquipoEmpleado, el Empleado es responsable (padre) [usando más tarde un EmployeeRepository].No se permiten duplicados.Eliminar un equipo elimina a todos los empleados en el equipo, si el empleado no está en otro equipo.Eliminar un Empleado solo elimina un Equipo, si el Equipo no contiene más Empleados.

Cartografía:

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();
    }
}

Creación de empleados y equipos:

    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);

Después de esto confirmo los cambios usando transaction.Commit (). La primera cosa extraña es que tengo que salvar Equipos y Empleados en lugar de uno solo de ellos (¿por qué?). Si solo salvo a todos los equipos o (Xor) a todos los empleados, obtengo unTransientObjectException:

"el objeto hace referencia a una instancia transitoria no guardada: guarde la instancia transitoria antes de vaciar. Escriba: Core.Domain.Model.Employee, Entity: Core.Domain.Model.Employee"

Cuando guardo todos los Equipos y Empleados creados, todo se guarda bien, PERO la tabla de relación que TeamEmployee tieneduplicaciones.

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

Así que en lugar de 4 relaciones hay 8 relaciones. 4 relaciones para el lado izquierdo y 4 relaciones para el lado derecho. :

¿En qué me equivoco?

Otras preguntas: cuando elimino un Equipo o un Empleado, ¿tengo que eliminar al equipo o al Empleado de la lista de Empleados del Equipo en el modelo de objeto o NHibernate hace el trabajo por mí (usando session.delete (..))?

Respuestas a la pregunta(4)

Su respuesta a la pregunta