1

Я использую NHibernat в сочетании с наследованием. Это означает, что у меня есть объект Parent и Child, который наследуется друг от друга, но каждый имеет свой собственный файл сопоставления, поэтому создаются отдельные таблицы.Использование .Any() в сочетании с NHibernate и наследованием

У меня были проблемы с функциональностью .Any(), когда я делаю следующее:

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

Я отладки исходного кода NHibernate, и я узнал, что, когда я запрос выполняется на объекте , он также перебирает все остальные классы, которые наследуют его. Это означает, что для вызова функции .Any набор результатов булевых значений заполняется. Но странно, что в DefaultQueryProvider.cs (строка 125) происходит следующее: return results [0];

Первый результат. Любой результат моего ChildObject, поэтому результат из моего ParentObject полностью игнорируется.

Я сделал UnitTest доказать это поведение:

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

Вы не ожидали бы, но этот тест блок выходит из строя. Если я тестирую один и тот же код с классом, который не имеет наследуемых от него других классов, проходит модульный тест.

я могу сделать обходной путь для этого с помощью:

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

, но я просто хочу, чтобы использовать функциональные возможности Any().

Возможно, у кого-нибудь есть решение?

Также добавлен в Bug Tracker NHibernate: https://nhibernate.jira.com/browse/NH-3939

ответ

0

Я нашел ответ. Вы можете отключить поведение наследования, выполнив следующие действия на отображение класса (FluentNhibernate в моем случае):

Polymorphism.Explicit(); 
+0

Отлично подходит для решения вашего дела. Теперь для тех, кто нуждается в полиморфизме, им нужно исправить ошибку в NHibernate, я думаю. –

0

Проблема здесь в том, что вы используете ParentObject как единое целое.

При проверке NHProfiler при выполнении

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

Вы увидите, что NHibernate получает все производный класс из БД, в том числе ваш ParentObject. Это приведет к нескольким операторам Select.

Это можно предотвратить, если вы изменили свой ParentObject на абстрактный и вывели из него класс. Затем проверьте свой производный класс, и вы получите результат, которого вы ожидаете.

+0

Его конструкция может должна быть исправлена, как вы пишете, но, похоже, есть ошибка в NHibernate тоже , Кажется, что NHibernate возвращает в случае «Any» только результат первого класса сущности (отсортированного по алфавиту по имени класса) вместо агрегирования результата всех классов сущностей, охватываемых запросом. –

Смежные вопросы