Fluent NHibernate: ¿Cómo crear un mapeo bidireccional de uno a muchos?


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

Detalles:

Tengo un objeto padre con muchos hijos. En mi caso, no tiene sentido que el hijo no tenga un padre, por lo que en la base de datos, me gustaría que la clave foránea del padre no tenga una restricción NULL. Estoy autogenerando mi base de datos a partir del mapeo fluido de NHibernate.

Tengo un padre con muchos objetos hijos como entonces:

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í está el mapeo con el que empecé:

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 Detail, el Summary_id no debe ser Null, porque en mi caso no tiene sentido tener un objeto de detalle no unido a la objeto resumen. Sin embargo, solo usando el mapa hasMany() deja la clave foránea Summary_id nullable.

Encontré en los documentos de NHibernate ( http://www.hibernate.org/hib_docs/nhibernate/html/collections.html ) que "Si el padre es requerido, use un one-to-many association".

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

Author: Nathan, 2008-11-22

1 answers

Para obtener una asociación bidireccional con una columna de clave foránea no nula en la tabla de Detalles, puede agregar la propiedad Owner sugerida, a References(...).CanNotBeNull () asigna en la clase DetailsMap, y hace que el final del resumen sea inverso.

Para evitar tener dos columnas de clave foránea diferentes para las dos direcciones de asociación, puede especificar los nombres de columna manualmente o nombrar las propiedades de una manera que dé el mismo nombre de columna para ambas direcciones. En este caso te sugiero renombrar los detalles.Propiedad del propietario a los detalles.Resumen.

Hice el id de resumen generado por increment para evitar problemas al insertar en la tabla ya que Summary currenty 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; }
}

Mapeo:

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
    }
}
 54
Author: Erik Öjebo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-22 09:36:47