powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / NHibernate (маппинги через Fluent) делает множество INSERT и DELETE
12 сообщений из 12, страница 1 из 1
NHibernate (маппинги через Fluent) делает множество INSERT и DELETE
    #37277470
NHibernate_User_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день, помогите найти ошибку в маппингах. (Используем Fluent).

При том, что записи и изменения entity на первый взгляд не было, т.е. при простом чтении (в пределах созданного UnitOfWork; без UnitOfWork проблема не возникает) получаем кучу INSERT и DELETE, которые сначала удаляют элементы таблицы со связью M:M, а потом вставляют обратно. Это убивает производительность. Команды отправляются после простого запроса (Session.CreateCriteria, а потом получаем для запроса список сущностей из базы), причем запрос был на одну сущность, а таблица M:M между двумя другими. (Видимо, запросом что-то просто сбрасывается или flush-ится, а сами INSERT и DELETE "накопились" ранее).

Вот сущности, связь между которыми вызывает проблему : назовем их Document и WareHouse.

Научился генерировать XML (метод .ExportTo), вот что в нем находится:

Document.hbm.xml:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
<class xmlns="urn:nhibernate-mapping-2.2" mutable="true" where="DeletionDate is null" name="Name.Document, Name, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="Document">
...
<bag cascade="all" name="WareHouses" table="DocumentWareHouse" mutable="true">
<key foreign-key="PFK_WareHouse_Document">
<column name="DocumentId" />
</key>
<many-to-many class="Name.WareHouse, Name, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<column name="WareHouseId" />
</many-to-many>
</bag>

В маппинге, а также в entity WareHouse ничего про Document нет.

Вот из entity Document:
Код: plaintext
1.
2.
3.
4.
5.
6.
        public virtual IEnumerable<WareHouse> WareHouses
        {
            get { return wareHouses; }
            protected set { wareHouses = value.ToList<WareHouse>(); }
        }
        protected List<WareHouse> wareHouses;
...
Рейтинг: 0 / 0
NHibernate (маппинги через Fluent) делает множество INSERT и DELETE
    #37277483
NHibernate_User_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Смущает также, откуда взялись mutable? Ведь не должны были, да и ключи у нас не mutable, а обычные, т.е. surrogate key. Их почему-то сгенерировал Fluent.

Вот что находится в маппинге для флуента на C#:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
    public class DocumentMap : ClassMap<Document>
    {
        ...
        public DocumentMap()
        {
            HasManyToMany<WareHouse>(x => x.WareHouses)
                .Table("DocumentWareHouse")
                .ParentKeyColumn("DocumentId")
                .ChildKeyColumn("WareHouseId").Cascade.All();
        }
    }

Вредные запросы идут такого вида:

Код: plaintext
1.
2.
3.
exec sp_executesql N'DELETE FROM dbo.DocumentWareHouse WHERE DocumentId = @p0',N'@p0 uniqueidentifier',@p0='B69B8F6F-F064-4AB0-8904-7AB502F006EF'

exec sp_executesql N'INSERT INTO dbo.DocumentWareHouse (DocumentId, WareHouseId) VALUES (@p0, @p1)',N'@p0 uniqueidentifier,@p1 smallint',@p0='B69B8F6F-F064-4AB0-8904-7AB502F006EF',@p1= 2 

В чем проблема? Очень помогла бы Ваша помощь, многоуважаемые!
...
Рейтинг: 0 / 0
NHibernate (маппинги через Fluent) делает множество INSERT и DELETE
    #37277880
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NHibernate_User_,

похоже, вы и сам знаете ответ: скорее всего где-нибудь ранее в рамках сессии поковыряли коллекцию, и в один момент nhibernate решил сохранить изменения в БД.
...
Рейтинг: 0 / 0
NHibernate (маппинги через Fluent) делает множество INSERT и DELETE
    #37277928
NHibernate_User_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Странно, уверен, что эта коллекция не трогается. В рамках задачи она как бы read-only. И задача-то - показать описание сущности Document пользователю, без каких-либо изменений :( Коллекция чисто проходится на чтение.

Может, все дело в cascade:all?
Из-за таких Insert и Delete вся программа никуда не годится :( Они не только здесь вылезают.
Вторую проблему, из-за которой у приложения отсутствует производительность (почему-то не работает LazyLoad), я изложу во втором топике.

А здесь так и не понятно, как быть.
...
Рейтинг: 0 / 0
NHibernate (маппинги через Fluent) делает множество INSERT и DELETE
    #37277943
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NHibernate_User_
Код: plaintext
1.
2.
3.
4.
5.
6.
        public virtual IEnumerable<WareHouse> WareHouses
        {
            get { return wareHouses; }
            protected set { wareHouses = value.ToList<WareHouse>(); }
        }
        protected List<WareHouse> wareHouses;


Упс... Просмотрел. У вас проблема не в маппингах, а вот в этой гадости: wareHouses = value.ToList<WareHouse>();
После загрузки сущности хибер подменяет реализацию коллекции на свою, с помощью которой отслеживает изменения в ней, и выполняет ленивую загрузка. А вы методом ToList() вынуждаете хибер сразу же загрузить коллекцию, и присваиваете полю новый объект, за которым хибер уже не следит.
...
Рейтинг: 0 / 0
NHibernate (маппинги через Fluent) делает множество INSERT и DELETE
    #37277945
NHibernate_User_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Самое интересное, что если не входить в UnitOfWork (isolationLevel : ReadCommitted), то никаких INSERT и DELETE не происходит :( Ведь изменения должны, по идее, не зависеть от UnitOfWork. Это вообще непонятно.
...
Рейтинг: 0 / 0
NHibernate (маппинги через Fluent) делает множество INSERT и DELETE
    #37277950
NHibernate_User_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Огромное спасибо за решение проблемы с LazyLoad! Пойду проверять :)
...
Рейтинг: 0 / 0
NHibernate (маппинги через Fluent) делает множество INSERT и DELETE
    #37278579
NHibernate_User_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А как нам решить следующую проблему? Мы, конечно, можем заменить код на такой:
Код: plaintext
1.
public virtual IEnumerable<WareHouse> WareHouses { get; protected set; }
но случится беда: в любом месте приложения мы сможем получить доступ к методам, изменяющим коллекцию внутри entity, а это противоречит принципам разработки.

Более того, у нас даже маппинги Fluent находятся в другой сборке.

Какие методы посоветуете, чтобы грамотно скрыть метод Add коллекции WareHouses от остальных частей приложения? Должно работать только через метод AddWareHouse самой entity.
...
Рейтинг: 0 / 0
NHibernate (маппинги через Fluent) делает множество INSERT и DELETE
    #37278636
NHibernate_User_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Извините за ошибку в предыдущем примере - имелось в виду, конечно же, IList, а не IEnumerable. Если же мы поставим IEnumerable, то даже само Entity не сможет изменить коллекцию.
Код: plaintext
1.
public virtual IList<WareHouse> WareHouses { get; protected set; }
...
Рейтинг: 0 / 0
NHibernate (маппинги через Fluent) делает множество INSERT и DELETE
    #37278698
NHibernate_User_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
C другой стороны, пробую сделать так:
Код: plaintext
1.
2.
3.
4.
5.
        public virtual IEnumerable<WareHouse> WareHouses
        {
            get { return wareHouses; }
        }
        protected virtual IList<WareHouse> wareHouses { get; set; }
и пытаюсь замапить не public WareHouses, a protected wareHouses,
но тут беда в том, что маппинги, как я сказал выше, в другой сборке и не видят entities :(
...
Рейтинг: 0 / 0
NHibernate (маппинги через Fluent) делает множество INSERT и DELETE
    #37278897
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NHibernate_User_,

Элементарно, Ватсон:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
public class Foo
{
    private IList<Bar> _bars;

    public virtual IList<Bar> Bars
    {
        get {return new List<Bars>(_bars).AsReadOnly();}
        private set {_bars = value;}
    }
}
...
Рейтинг: 0 / 0
NHibernate (маппинги через Fluent) делает множество INSERT и DELETE
    #37281161
NHibernate_User_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Огромное спасибо.
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / NHibernate (маппинги через Fluent) делает множество INSERT и DELETE
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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