Нет постоянной ошибки при использовании NHibernate с ASP.NET модульные тесты работают корректно

#c# #nhibernate #webforms

#c# #nhibernate #веб-формы

Вопрос:

У меня интересная ошибка с ASP.NET приложение webforms, над которым я работал. Я использую NHibernate (обычный, не fluent), подключаюсь к базе данных sqlite со следующим отображением и конфигурацией:

 <?xml version="1.0" encoding="utf-8"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>    
    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
    <property name="connection.driver_class">NHibernate.Driver.SQLiteDriver</property>
    <property name="connection.connection_string">Data Source=C:PathToDatabase.db;Version=3</property>
    <property name="dialect">NHibernate.Dialect.SQLiteDialect</property>
    <property name="query.substitutions">true=1;false=0</property>
    <property name="show_sql">true</property>
  </session-factory>
</hibernate-configuration>
  

Существует несколько объектов, но следующий простой пример:

 <?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="XBMC.Data"
                   namespace="XBMC.Data.Model.Domain">
  <class name="Genre" table="genre">
    <id name="Id" column="idGenre" type="int">
      <generator class="native"/>
    </id>
    <property name="Name" column="strGenre" type="string" />
  </class>
</hibernate-mapping>
  

Этот файл настроен как встроенный ресурс. Это идет рука об руку с:

 public class Genre : IRecord
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
}
  

Также существует NHibernateHelper класс, который используется для захвата сеанса (большую часть этого я почерпнул из http://nhforge.org/wikis/howtonh/your-first-nhibernate-based-application.aspx это фантастический учебник по началу работы с NHibernate).

 public class NHibernateHelper
{
    private static ISessionFactory _sessionFactory;

    private static ISessionFactory SessionFactory
    {
        get
        {
            if (_sessionFactory == null)
            {
                Configuration config = new Configuration();
                config.Configure();

                config.AddAssembly(typeof(IRecord).Assembly);

                _sessionFactory = config.BuildSessionFactory();
            }

            return _sessionFactory;
        }
    }

    public static ISession OpenSession()
    {
        return SessionFactory.OpenSession();
    }
}
  

Пока все хорошо. Я следовал подходу разработки, основанному на тестировании, и у меня есть несколько тестовых примеров, подобных следующему:

 [Test]
public void CanLoadGenre()
{
    using (ISession session = NHibernateHelper.OpenSession())
    {
        Genre g = session.Get<Genre>(759);
        Assert.That(g.Name, Is.EqualTo("Action"));
    }
}
  

Они работают нормально (я использую последнюю версию NUnit с TestDriven.ЧИСТЫЙ FWIW). Я вижу SQL, сгенерированный NHibernate, и все выглядит идеально. Проблемы начинаются, когда я пытаюсь использовать свою библиотеку в ASP.NET приложение.

Что я хотел бы сделать, так это привязать ListView к ObjectDataSource. Для этого я написал GenreProvider, и он просто получает список доступных Genre объектов. В модульных тестах это работает нормально. Как только в приложении ASP запускается что-либо, связанное с NHibernate, я получаю NHibernate.MappingException: No persister for: Genre исключения, и все идет наперекосяк.

В частности, сбой в следующей строке (оператор return):

 using (ISession session = NHibernateHelper.OpenSession())
    return session.CreateCriteria(typeof(T).Name).List<T>();
  

(Это в общем классе репозитория — однако он отлично работает во время модульных тестов).

Итак, вкратце: NHibernate, похоже, работает корректно во время моих модульных тестов, но терпит неудачу при использовании в приложении ASP. Я уверен, что это проблема в моей конфигурации, но я проверил Google на наличие ошибок ‘no persister’ (решения включали обеспечение настройки ‘Embedded resource’ для файлов сопоставления, различные комбинации AddClass , AddAssembly и т.д. В конфигурации, настройки <mapping assembly="..." /> в моей конфигурации и т.д., Но безуспешно), Но, скорее всего, не вижу дерева для деревьев.

Кто-нибудь может пролить свет на это и помешать мне сойти с ума? (При необходимости я могу опубликовать больше кода, но воздержался, чтобы предотвратить информационную перегрузку!)

Спасибо!

Ответ №1:

Попробуйте добавить это в свой hibernate-configuration файл (или даже в ваш web.config , если там оно находится)

 <property name="current_session_context_class">web</property>
  

Комментарии:

1. Фантастика, спасибо. Мне также пришлось добавить HttpModule в мое веб-приложение — для всех, у кого еще есть эта проблема, хорошее руководство о том, как правильно запустить NHibernate с ASP, находится здесь: dotnetslackers.com/articles/aspnet /… .