44 votes

NHibernate Fluent: Comment créer un mappage bidirectionnel un-à-plusieurs?

Question de base: Comment puis-je créer une bidirectionnel un-à-plusieurs carte dans NHibernate Fluent?

Détails:

J'ai un parent de l'objet avec de nombreux enfants. Dans mon cas, il est sans signification pour l'enfant de ne pas avoir de parent, de sorte que dans la base de données, je voudrais la clé étrangère à la mère d'avoir de contrainte not NULL. Je suis auto-génération de ma base de données à partir de la fluidité de la NHibernate de cartographie.

J'ai une mère avec de nombreux objets enfants de la sorte:

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?
}

Voici la cartographie, j'ai commencé avec:

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

Dans la table de Détail, la Summary_id doit être Non Null, parce que dans mon cas, il est inutile d'avoir un Détail de l'objet n'est pas attaché à la résumé de l'objet. Cependant, en utilisant seulement la HasMany (carte) quitte le Summary_id clé étrangère nullable.

J'ai trouvé dans le NHibernate docs (http://www.hibernate.org/hib_docs/nhibernate/html/collections.html) que "Si le parent est nécessaire, utiliser une bidirectionnel un-à-plusieurs association".

Alors, comment puis-je créer l'bidirectionnel un-à-plusieurs carte dans NHibernate Fluent?

55voto

Erik Öjebo Points 6937

Pour obtenir une association bidirectionnelle avec un non-nulle de la colonne de la clé étrangère dans la table Détails vous pouvez ajouter l'a suggéré la propriété du Propriétaire, une des Références(...).CanNotBeNull() de la cartographie dans les DetailsMap classe, et de faire le Résumé de fin inverse.

Pour éviter d'avoir deux colonnes de clé étrangère pour les associations de deux directions, vous pouvez spécifier les noms de colonne manuellement ou nom les propriétés d'une manière qui donne le même nom de colonne pour les deux directions. Dans ce cas, je suggère de renommer les Détails.La propriété du propriétaire pour les Détails.Résumé.

J'ai fait le Résumé de l'id généré par incrément pour éviter des problèmes lors de l'insertion dans la table depuis Résumé currenty n'a pas de colonnes en plus de l'id.

Domaine:

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

Cartographie:

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
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X