1

Je me suis heurté à un problème de conversion de ma cartographie NH Fluent en architecture Sharp. J'aime la plate-forme pour sa facilité, mais il semble gérer les mappages d'entités légèrement différemment de la pure NH Fluent.S # arp Architecture Mappage fluide pour l'entité auto-référencée (structure arborescente)

J'ai une entité 'Catégorie' qui est une structure arborescente simple. Je dois remplacer l'auto-mapping car il y a une propriété M: M que j'ai besoin d'ajouter (pas inclus dans le code ci-dessous).

Lorsque je crée des tests sur le référentiel, la méthode GetAll renvoie toutes les catégories comme il se doit, mais la propriété Children se boucle tout seul. c'est-à-dire que la liste des enfants pour chaque catégorie ne contient que lui-même, en boucle ininterrompue.

/// L'entité ///

public class Category : Entity 
{ 
    public Category() 
    { 
     InitMembers(); 
    } 

    /// <summary> 
    /// Creates valid domain object 
    /// </summary> 
    public Category(string name) 
     : this() 
    { 
     Name = name; 
    } 

    /// <summary> 
    /// Creates valid domain object 
    /// </summary> 
    public Category(string name, int depth) 
     : this() 
    { 
     Name = name; 
     Depth = depth; 
    } 

    private void InitMembers() 
    { 
     Children = new List<Category>(); 
    } 

    [DomainSignature] 
    [NotNullNotEmpty] 
    public virtual string Name { get; protected set; } 

    [DomainSignature] 
    public virtual int Depth { get; protected set; } 

    public virtual Category Parent { get; set; } 

    public virtual IList<Category> Children { get; private set; } 

    public virtual void AddChild(Category category) 
    { 
     category.Parent = this; 
     Children.Add(category); 
    } 
} 

/// La cartographie ///

public class CategoryMap : IAutoMappingOverride<Category> 
{ 
    public void Override(AutoMap<Category> mapping) 
    { 
     mapping.Id(x => x.Id, "CategoryId") 
      .WithUnsavedValue(0) 
      .GeneratedBy.Identity(); 

     mapping.Map(x => x.Name).WithLengthOf(50); 

     mapping.Map(x => x.Depth); 

     mapping.HasMany<Category>(x => x.Children) 
      .Inverse() 
      .Cascade.All() 
      .KeyColumnNames.Add("Parent_id") 
      .AsBag(); 
    } 
} 

/// Les tests de référentiel de données ///

[TestFixture] 
[Category("DB Tests")] 
public class CategoryRepositoryTests : RepositoryTestsBase 
{ 
    private readonly IRepository<Category> _repository = new Repository<Category>(); 

    protected override void LoadTestData() 
    { 
     CreatePersistedCategory("Root 1"); 
     CreatePersistedCategory("Root 2"); 
     CreatePersistedCategoryWithChildren("Level 1", "Level 2", "Level 3"); 
    } 

    [Test] 
    public void CanGetAllCategories() 
    { 
     var categories = _repository.GetAll(); 
     categories.ShouldNotBeNull(); 
     categories.Count.ShouldEqual(5); 
    } 

    [Test] 
    public void CanGetCategoryById() 
    { 
     var category = _repository.Get(1); 
     category.Name.ShouldEqual("Root 1"); 
     category.Depth.ShouldEqual(1); 
    } 

    [Test] 
    public void CanGetCategoryChildren() 
    { 
     var category = _repository.Get(3); 
     category.Name.ShouldEqual("Level 1"); 
     category.Depth.ShouldEqual(1); 
     category.Children.ShouldNotBeNull(); 
     category.Children.Count.ShouldEqual(1); 
     category.Children[0].Name.ShouldEqual("Level 2"); 
     category.Children[0].Depth.ShouldEqual(2); 
     category.Children[0].Children.ShouldNotBeNull(); 
     category.Children[0].Children.Count.ShouldEqual(1); 
     category.Children[0].Children[0].Name.ShouldEqual("Level 3"); 
     category.Children[0].Children[0].Depth.ShouldEqual(3); 
    } 


    private void CreatePersistedCategory(string categoryName) 
    { 
     var category = new Category(categoryName, 1); 
     _repository.SaveOrUpdate(category); 
     FlushSessionAndEvict(category); 
    } 

    private void CreatePersistedCategoryWithChildren(string category1, string category2, string category3) 
    { 
     var cat1 = new Category(category1, 1); 
     var cat2 = new Category(category2, 2) { Parent = cat1 }; 
     var cat3 = new Category(category3, 3) { Parent = cat2 }; 
     cat1.AddChild(cat2); 
     cat2.AddChild(cat3); 
     _repository.SaveOrUpdate(cat1); 
     FlushSessionAndEvict(cat1); 
    } 
} 
+0

Je suggère de regarder SQL que génère NHibernate. – queen3

+0

Dans les tests Hibernate.cfg.xml j'ai défini: true. La configuration de log4net est configurée, mais aucun fichier journal n'est créé. – Jordan

+0

show_sql autant que je sache se réfère à la sortie de stdout (enfin, je peux me tromper). – queen3

Répondre

1

Géré pour travailler, après beaucoup de peaufinage. Le truc Auto-cartographie bien que très cool nécessite une certaine compréhension. RTFM pour moi ...

0

À vrai dire, je n'avais pas encore découvert ou compris les conventions d'Auto-mapping: TableNameConvention, PrimaryKeyConvention et spécifiquement HasManyConvention. Le code arp S # par défaut aime à pluraliser ses tables de base de données, et a des colonnes Id avec le nom de la table préfixé, c'est-à-dire CategoryId. Je n'aime pas pluraliser, et j'aime les colonnes Id cohérentes, "Id" suffit. Et mes références de clés étrangères étaient de style différent, j'aime Category_id.

public class HasManyConvention : IHasManyConvention 
{ 
    public bool Accept(IOneToManyCollectionInstance oneToManyPart) 
    { 
     return true; 
    } 

    public void Apply(IOneToManyCollectionInstance oneToManyPart) 
    { 
     oneToManyPart.KeyColumnNames.Add(oneToManyPart.EntityType.Name + "_id"); 
    } 
} 

public class PrimaryKeyConvention : IIdConvention 
{ 
    public bool Accept(IIdentityInstance id) 
    { 
     return true; 
    } 

    public void Apply(IIdentityInstance id) 
    { 
     id.Column("Id"); 
    } 
} 

Mais maintenant, tout cela fonctionne un régal mais je maintenant un problème avec de nombreux à-plusieurs. Il semble que S # arp ne les supporte pas encore. Mes remplacements de mappage ne semblent pas fonctionner, rien n'est inséré dans ma table de mappage dans la base de données.

Voir: S#arp Architecture many-to-many mapping overrides not working

0

je n'étais pas en mesure de résoudre cela en utilisant des conventions fluide et de ce que je l'ai vu la recherche autour de ce moment ne peut pas être fait en utilisant les conventions. Fluent suppose qu'un arbre auto-référencé comme celui-ci est de type many-to-many, donc dans votre cas, je suppose que vous essayez de tracer une relation many-to-many et donc il ne devrait pas y avoir de problème.

Dans mon cas, j'avais besoin de le mapper comme plusieurs-à-un (pour une hiérarchie stricte des commentaires imbriqués et des réponses). La seule façon que je pouvais comprendre pour faire cela était de définir un override pour la classe parent-enfant pour mapper cette relation. Fortunately it is very easy.

J'aimerais bien savoir s'il y a un moyen de mapper avec succès de nombreuses-à-une comme ça avec les conventions.

Questions connexes