5

que tienen un modelo simple de Fluido NHibernate con dos clases relacionadas:Fluido NHibernate uno-a-muchos relación de ajuste de clave externa a null

public class Applicant 
    { 
     public Applicant() 
     { 
      Tags = new List<Tag>(); 
     } 

     public virtual int Id { get; set; } 

     //other fields removed for sake of example 

     public virtual IList<Tag> Tags { get; protected set; } 

     public virtual void AddTag(Tag tag) 
     { 
      tag.Applicant = this; 
      Tags.Add(tag); 
     } 
    } 


public class Tag 
{ 
    public virtual int Id { get; protected set; } 
    public virtual string TagName { get; set; } 

    public virtual Applicant Applicant { get; set; } 
} 

Mi mapeo fluidez es la siguiente:

public class ApplicantMap : ClassMap<Applicant> 
    { 
     public ApplicantMap() 
     { 
      Id(x => x.Id); 

      HasMany(x => x.Tags).Cascade.All(); 
     } 
    } 

    public class TagMap : ClassMap<Tag> 
    { 
     public TagMap() 
     { 
      Id(x => x.Id); 
      Map(x => x.TagName); 

      References(x => x.Applicant).Not.Nullable(); 
     } 
    } 

Siempre Intento actualizar un solicitante (insertar uno nuevo funciona bien), falla y veo la siguiente excepción SQL en los registros:

11:50:52.695 [6] DEBUG NHibernate.SQL - UPDATE [Tag] SET Applicant_id = null WHERE Applicant_id = @p0;@p0 = 37 [Type: Int32 (0)] 
11:50:52.699 [6] ERROR NHibernate.AdoNet.AbstractBatcher - Could not execute command: UPDATE [Tag] SET Applicant_id = null WHERE Applicant_id = @p0 System.Data.SqlClient.SqlException (0x80131904): Cannot insert the value NULL into column 'Applicant_id', table 'RecruitmentApp.dbo.Tag'; column does not allow nulls. UPDATE fails. 

¿Por qué NHibernate intenta actualizar la tabla de etiquetas y establece Applicant_id en nulo? Estoy perdido con esto.

Respuesta

13

El conjunto Applicant.Tags a Inverse indicará a NHibernate que guarde Tags después del Applicant.

public class ApplicantMap : ClassMap<Applicant> 
{ 
    public ApplicantMap() 
    { 
     Id(x => x.Id); 

     HasMany(x => x.Tags).Cascade.All().Inverse(); 
    } 
} 

más detalle:

Inverse (en contraposición a .Not.Inverse()) significa el otro lado de la relación (en este caso, cada Tag) es responsable de mantener la relación. Por lo tanto, NHibernate sabe que el Applicant se debe guardar primero para que Tag tenga una clave externa válida para su Applicant.

La regla de oro: La entidad que contiene la clave externa suele ser el propietario, por lo que la otra tabla debe tener Inverse

+0

funcionó de maravilla. ¡Gracias! Todavía estoy un poco confundido sobre lo que significa invertir, pero voy a leer un poco. Aunque no lo veo en la documentación. – arknotts

+0

Muchas gracias por resolver el problema funcionó sin ningún problema. – Desmond

Cuestiones relacionadas