#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 /… .