2008-11-22 23 views
43

Pregunta básica: ¿Cómo puedo crear un mapa bidireccional de uno a muchos en Fluiber NHibernate?Fluidez NHibernate: ¿Cómo crear un mapeo bidireccional de uno a muchos?

Detalles:

que tienen un objeto padre con muchos niños. En mi caso, no tiene sentido que el niño no tenga un padre, por lo tanto, en la base de datos, me gustaría que la clave externa del padre tenga una restricción NOT NULL. Estoy generando automáticamente mi base de datos del mapeo de NHibernate fluido.

tengo un padre con muchos objetos secundarios de este modo:

public class Summary 
{ 
    public int id {get; protected set;} 

    public IList<Detail> Details {get; protected set;} 
} 

public class Detail 
{ 
    public int id {get; protected set;} 

    public string ItemName {get; set;} 

    /* public Summary Owner {get; protected set;} */ //I think this might be needed for bidirectional mapping? 
} 

Aquí es el mapeo Empecé con:

public class SummaryMap : ClassMap<Summary> 
{ 
    public SummaryMap() 
    { 
     Id(x => x.ID); 

     HasMany<Detail>(x => x.Details); 
    } 
} 

public class DetailMap : ClassMap<Detail> 
{ 
    public DetailMap() 
    { 
     Id(x => x.ID); 

     Map(x => x.ItemName).CanNotBeNull(); 
    } 
} 

En la tabla detalle, el Summary_id debe ser no nulo, porque en mi caso no tiene sentido tener un objeto Detail no asociado al objeto de resumen . Sin embargo, el uso del mapa HasMany() deja la clave externa Summary_id nullable.

Encontré en los documentos NHibernate (http://www.hibernate.org/hib_docs/nhibernate/html/collections.html) que "Si se requiere el padre, use una asociación uno a muchos bidireccional".

Entonces, ¿cómo puedo crear el mapa bidireccional de uno a muchos en Fluent NHibernate?

Respuesta

54

Para obtener una asociación bidireccional con una columna de clave externa no nula en la tabla Detalles, puede agregar la propiedad Propietario sugerida, una asignación Referencias (...). CanNotBeNull() en la clase DetailsMap y crear el Resumen final inverso.

Para evitar tener dos columnas de clave externa diferentes para las dos direcciones de asociación, puede especificar los nombres de columna manualmente o nombrar las propiedades de manera que proporcione el mismo nombre de columna para ambas direcciones. En este caso, sugiero cambiar el nombre de la propiedad Details.Owner a Details.Summary.

Realicé el ID de resumen generado por incremento para evitar problemas al insertar en la tabla ya que Summary actualy no tiene columnas además de id.

Dominio:

public class Detail 
{ 
    public int id { get; protected set; } 
    public string ItemName { get; set; } 

    // Renamed to use same column name as specified in the mapping of Summary.Details 
    public Summary Summary {get; set;} 
} 

public class Summary 
{ 
    public Summary() 
    { 
     Details = new List<Detail>(); 
    } 

    public int id { get; protected set; } 
    public IList<Detail> Details { get; protected set; } 
} 

Mapping:

public class DetailMap : ClassMap<Detail> 
{ 
    public DetailMap() 
    { 
     Id(x => x.id) 
      .GeneratedBy.Native(); 

     Map(x => x.ItemName) 
      .CanNotBeNull(); 

     References<Summary>(x => x.Summary) 
      // If you don't want to rename the property in Summary, 
      // you can do this instead: 
      // .TheColumnNameIs("Summary_id") 
      .CanNotBeNull(); 
    } 
} 

public class SummaryMap : ClassMap<Summary> 
{ 
    public SummaryMap() 
    { 
     Id(x => x.id) 
      .GeneratedBy.Increment(); 

     HasMany<Detail>(x => x.Details) 
      .IsInverse() 
      .AsBag(); // Use bag instead of list to avoid index updating issues 
    } 
} 
+8

¿Realmente no hay manera de hacer que la columna de clave externa "no anulable" sin añadir una referencia a los padres sobre el niño ? –

+2

+1 Desearía poder votar nuevamente. –

Cuestiones relacionadas