1

J'utilise NHibernat en combinaison avec l'héritage. Cela signifie que j'ai un objet parent et un objet enfant qui héritent l'un de l'autre, mais que chacun a son propre fichier de mappage, donc des tables séparées sont créées.Utiliser .Any() en combinaison avec NHibernate et l'héritage

J'avais des problèmes avec la fonctionnalité .Tout() quand je fais ce qui suit:

var value = session.Query<ParentObject>().Any(t => t.Name.Equals(name)); 

J'ai débogage du code source NHibernate et j'ai découvert que lorsqu'une requête i effectuée sur un objet , il boucle aussi à travers toutes les autres classes qui en héritent. Cela signifie que pour un appel de fonction .Any, un ensemble de résultats de booléens est rempli. Mais la chose étrange est que dans DefaultQueryProvider.cs (ligne 125) ce qui suit arrive: retourner les résultats [0];

Le premier résultat est le résultat .Any de mon objet ChildObject, donc le résultat de mon objet parent est complètement ignoré.

J'ai fait une UnitTest pour prouver ce comportement:

[TestMethod] 
    public void TestInheritance() 
    { 
     var name = "test"; 
     var sessionFactory = CreateSessionFactory(database2); 

     using (var session = sessionFactory.OpenSession()) 
     using (var transaction = session.BeginTransaction()) 
     { 
      var testObject = new ParentObject(); 
      testObject.SetName(name); 

      session.SaveOrUpdate(testObject); 
      transaction.Commit(); 

      var value = session.Query<ParentObject>().Any(t => t.Name.Equals(name)); 

      Assert.IsTrue(value); 
     } 
    } 

Vous ne penseriez pas, mais cela échoue test unitaire. Si je teste le même code avec une classe dont aucune autre classe n'en hérite, le test unitaire est réussi.

Je peux faire une solution de contournement pour cela en utilisant:

var value = session.Query<ParentObject>().FirstOrDefault(t => t.Name.Equals(name)) != null 

mais je veux juste utiliser la fonctionnalité Tout().

Est-ce que quelqu'un a peut-être une solution pour cela?

ajouté également dans le Bug Tracker NHibernate: https://nhibernate.jira.com/browse/NH-3939

Répondre

0

J'ai trouvé la réponse. Vous pouvez désactiver le comportement de l'héritage en procédant comme suit la classe de cartographie (FluentNhibernate dans mon cas):

Polymorphism.Explicit(); 
+0

Idéal pour résoudre votre cas. Maintenant, pour ceux qui ont besoin du polymorphisme, ils ont besoin d'une correction de bogue dans NHibernate, je pense. –

0

Le problème ici est que vous utilisez votre ParentObject comme une entité.

Lorsque vous vérifiez NHProfiler lors de l'exécution

session.Query<ParentObject>().ToList() 

Vous verrez que NHibernate reçoit toute classe dérivée de la db, y compris votre ParentObject. Cela entraînera plusieurs instructions Select.

Vous pouvez empêcher ce comportement lorsque vous modifiez votre ParentObject pour en extraire une classe. Puis vérifiez par rapport à votre classe dérivée et vous obtiendrez le résultat que vous attendez.

+0

Sa conception peut avoir besoin d'être fixé que vous écrivez, mais il semble qu'il y ait un bogue dans NHibernate trop . NHibernate semble retourner dans le cas de 'Any' uniquement le résultat de la première classe d'entité interrogée (triée par ordre alphabétique selon son nom de classe), au lieu d'agréger le résultat de toutes les classes d'entités couvertes par la requête. –