C # NHibernate — доступ к списку элементов выдает ошибку (не удалось лениво инициализировать …)

#c# #asp.net-mvc #nhibernate #lazy-initialization

#c# #asp.net-mvc #nhibernate #ленивая инициализация

Вопрос:

Я использую MVC2, NHibernate 3.2.

Мои классы:

 public class NHibernateHelper
{

    private static ISessionFactory _sessionFactory;

    private static ISessionFactory SessionFactory
    {
        get
        {
            if (_sessionFactory == null)
            {
                var configuration = new Configuration();
                configuration.Configure();
                configuration.AddAssembly(typeof(EstoqueEquipamento).Assembly);
                _sessionFactory = configuration.BuildSessionFactory();
            }
            return _sessionFactory;
        }
    }

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

Я запрашиваю элемент с помощью этого:

  public Car GetCar(object pk)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {

                return session.Get<Car>(pk);
            }
        }
  

Отображение Car:

 <?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateClasses" namespace="NHibernateClasses.Entities">
    <class name="Car" table="STACK.CAR" lazy="true" dynamic-update="true" dynamic-insert="true" >
        <id name="CarId" column="CAR_ID" type="Int32" unsaved-value="0">
            <generator class="sequence">
                <param name="sequence">SQ_CAR</param>
            </generator>
        </id>
        <bag name="TireList" inverse="true" generic="true" lazy="true" >
            <key>
                <column name="CarId"/>
            </key>
            <one-to-many class="Tire" />
        </bag>




        <property name="Plate" type="String" column="MAH_PLATE" />



    </class>
</hibernate-mapping>
  

Отображение шины:

 <?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateClasses" namespace="NHibernateClasses.Entities">
    <class name="Tire" table="STACK.Tire" lazy="true" dynamic-update="true" dynamic-insert="true" >
        <id name="TireId" column="Tire_ID" type="Int32" unsaved-value="0">
            <generator class="sequence">
                <param name="sequence">SQ_Tire</param>
            </generator>
        </id>


        <property name="Brand" type="String" column="MAH_BRAND" />



    </class>
</hibernate-mapping>
  

Затем я запрашиваю элемент:

 var car = GetCar(1);//works just fine
var tirelist = car.Tires;//throws error!
  

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

Инициализация[Car] — не удалось лениво инициализировать коллекцию role: Car.TireList, ни один сеанс или session не был закрыт

Дайте мне знать, если вам также понадобится файл конфигурации.

Спасибо

Ответ №1:

В getCar вы закрываете сеанс (из-за using ), прежде чем получить доступ к коллекции шин позже в вашем коде. Коллекции загружаются лениво по умолчанию в NHibernate, поэтому убедитесь, что вы извлекли коллекцию перед завершением транзакции. Вы могли бы использовать ускоренную загрузку, чтобы убедиться, что NHibernate также загружает дочернюю коллекцию.

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

1. Вы имеете в виду, что в методе GeCar я должен вызвать car . Список шин? Если я сделаю его не ленивым, будет ли он работать как есть?

2. Это также допустимые методы для обеспечения того, чтобы NHibernate загружал коллекцию до закрытия сеанса.

3. Я использую общий репозиторий для получения элементов. Я имею в виду, что один и тот же Get используется для дюжины объектов, поэтому я не могу вызвать свойство list. Кроме того, нетерпеливая вещь, похоже, попадает в ту же проблему.

4. Вы могли бы попробовать изменить сопоставление, чтобы указать, что коллекция должна загружаться быстро.

5. Я попытался установить для lazy значение false для всех сопоставлений, и теперь приложение работает невероятно медленно, по правде говоря, я пока не смог выполнить ни одного запроса, оно просто загружается бесконечно.