powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / LazyInitializationException illegal access to loading collection при маппинге one-to-many
5 сообщений из 5, страница 1 из 1
LazyInitializationException illegal access to loading collection при маппинге one-to-many
    #38021548
Lexxxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть пара сущностей:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
namespace Shop.Domain
{
    public class Order : Entity
    {
        private User user;

        public virtual string Name { get; set; }

        public virtual User User
        {
            get
            {
                return this.user;
            }
            set
            {
                if (value == this.user) return;

                if (this.user != null)
                    this.user.RemoveOrder(this);

                if (value != null)
                    value.AddOrder(this);

                this.user = value;
            }
        }
    }
}



Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
using System;
using System.Collections.Generic;

namespace Shop.Domain
{
    public class User : Entity
    {
        private IList<Order> orders = new List<Order>();

        public virtual string Name { get; set; }

        public virtual IEnumerable<Order> Orders { get { return this.orders; } }

        public virtual void AddOrder(Order order)
        {
            if (order == null) throw new ArgumentNullException("order");

            if (!this.orders.Contains(order))
            {
                this.orders.Add(order);
                order.User = this;
            }
        }

        public virtual void RemoveOrder(Order order)
        {
            if (order == null) throw new ArgumentNullException("order");

            if (this.orders.Contains(order))
            {
                this.orders.Remove(order);
                order.User = null;
            }
        }
    }
}



И их маппинги:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
using FluentNHibernate.Mapping;
using Shop.Domain;

namespace NHInfrastructure.Mappings
{
    class UserMap : ClassMap<User>
    {
        public UserMap()
        {
            Id(x => x.ID).GeneratedBy.HiLo("100");
            Map(x => x.Name);

            HasMany(x => x.Orders)
                .Access.ReadOnlyPropertyThroughLowerCaseField()
                .Cascade.SaveUpdate();
        }
    }
}

using FluentNHibernate.Mapping;
using Shop.Domain;

namespace NHInfrastructure.Mappings
{
    class OrderMap : ClassMap<Order>
    {
        public OrderMap()
        {
            Id(x => x.ID).GeneratedBy.HiLo("100");
            Map(x => x.Name);
            
            References(x => x.User)
                .Not.Nullable()
                .Cascade.SaveUpdate();
        }
    }
}



При выполнении кода

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
class Program
    {
        static void Main(string[] args)
        {
            var user = new User { Name = "TestUser" };
            var o = new Order { Name = "TestOrder" };
            o.User = user;
            var userID = 0;

            using (var session = NHManager.GetSession())
            {
                using (var tr = session.BeginTransaction())
                {
                    userID = (int)session.Save(user);
                    tr.Commit();
                }
            }

            var u = NHManager.GetSession().Load<User>(userID);
            // На следующей строке получаем исключение.
            var e = u.Orders.Count() == 1;
        }
    }



Получаем исключение NHibernate.LazyInitializationException с описанием illegal access to loading collection.
Что ему не так? Как это побороть?
...
Рейтинг: 0 / 0
LazyInitializationException illegal access to loading collection при маппинге one-to-many
    #38021570
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lexxxxx,

а метод Load используется умышленно? Чем Get не подошёл?
...
Рейтинг: 0 / 0
LazyInitializationException illegal access to loading collection при маппинге one-to-many
    #38021605
Lexxxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolYUtor,

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

(P.S. строка .Access.ReadOnlyPropertyThroughLowerCaseField() в мапинге UserMap указана по ошибке и в коде отсутствует.)
...
Рейтинг: 0 / 0
LazyInitializationException illegal access to loading collection при маппинге one-to-many
    #38021651
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lexxxxx,

Это не совсем та отложенная загрузка, о которой вы думаете. Начнём с простого:
1. Get() грузит из базу только таблицу с самой сущностью, при этом заполняются все поля, которые есть в этой таблицы. Все связи (включая коллекции) не грузятся, пока не будут вызываны.
2. Load() - не грузит из базы вообще ничего! Он возвращает вам пустой прокси-класс. И при первом же обращении к полям полезет в базу с запросом к основной таблице. Его использование оправдано в некоторых случаях, но явно не в этом.

PS. Влючите в конфиге хибера LogSqlToConsole, и смотрите, что реально происходит.
...
Рейтинг: 0 / 0
LazyInitializationException illegal access to loading collection при маппинге one-to-many
    #38021675
Lexxxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolYUtor,

Спасибо за подсказку об отложенной загрузке.
Проблема решена путем добавления в OrderMap строки .Access.LowerCaseField() для свойства User.
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / LazyInitializationException illegal access to loading collection при маппинге one-to-many
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]