1

J'essaie de créer un arbre dans une table unique en utilisant Fluent Nhibernate. La table doit ressembler à ceci: enter image description hereException sur le mappage On-To-Many dans une table. Impossible de trouver la propriété ni le champ X dans la classe Y

Modèle Classe:

public class Category 
{ 
    public virtual int CategoryId { get; set; } 
    public virtual string CategoryName { get; set; } 
    public virtual Category ParentCategory { get; set; } 
    public virtual IList<Category> ChildCategory { get; } = new List<Category>(); 
} 

mapping class:

public class CategoryMap : ClassMap<Category> 
{ 
    public CategoryMap() 
    { 
     Id(x => x.CategoryId).GeneratedBy.Increment(); 
     Map(x => x.CategoryName).Not.Nullable(); 

     References(x => x.ParentCategory).Column("ParentCategoryId").Access.CamelCaseField(); 

     HasMany(x => x.ChildCategory) 
      .Cascade.AllDeleteOrphan() 
      .AsSet() 
      .KeyColumn("CategoryId") 
      .Access.CamelCaseField(); 
    } 
} 

retour ORM exception suivante:

NHibernate.PropertyNotFoundException: Impossible de trouver la propriété ni champ 'childCategory' dans la classe 'MyProj.Models.Category'

J'étudie seulement NH. Qu'est-ce que je fais mal?

Répondre

1

Vous ne pouvez pas utiliser les propriétés automatiques avec des stratégies d'accès aux champs. Vous avez besoin d'un backing field explicite pour que cela fonctionne, et son nom doit correspondre à la stratégie de nommage que vous avez choisie.

Donc dans votre cas, changez votre classe:

public class Category 
{ 
    public virtual int CategoryId { get; set; } 
    public virtual string CategoryName { get; set; } 
    public virtual Category ParentCategory { get; set; } 

    private ISet<Category> childCategory = new HashSet<Category>(); 
    public virtual ISet<Category> ChildCategory { get { return childCategory; } } 
} 

Puisque vous mappage comme un ensemble, j'ai plus changé votre IList pour un ISet.

Si vous voulez un autre nom pour le champ de sauvegarde, choisissez une autre stratégie de dénomination. Voir here une liste d'entre eux pour le mappage hbm. (Ou get it in NHibernate reference documentation.) Fluent devrait avoir les mêmes stratégies.

Vous pouvez utiliser un champ de sauvegarde et supprimer le .Access.CamelCaseField() de vos mappages et ajouter un paramètre à votre propriété ChildCategory.

+0

Merci de votre réponse. Je corrige la classe 'Category' et obtiens une autre exception' NHibernate.PropertyNotFoundException: Impossible de trouver la propriété ni le champ 'parentCategory' dans la classe 'MyProj.Models.Category'' – Seva

+1

@Seva, supprime '.Access.CamelCaseField()' de 'ParentCategory 'cartographie. Pas besoin d'utiliser ça quand la propriété a un setter. –

0

j'ai changé la classe de cartographie sur les points suivants:

public class Category 
    { 
     private ISet<Category> childCategories; 
     private Category parentCategory; 

     public Category() 
     { 
      childCategories = new HashSet<Category>(); 
     } 

     public virtual int CategoryId { get; protected set; } 

     public virtual string CategoryName { get; set; } 

     public virtual ReadOnlyCollection<Category> ChildCategories 
     { 
      get 
      { 
       return new ReadOnlyCollection<Category>(new List<Category>(childCategories)); 
      } 
     } 

     public virtual Category ParentCategory 
     { 
      get 
      { 
       return parentCategory; 
      } 
     } 
} 

Et il est de générer table avec des exceptions.