Пакетное обновление в NHibernate - PullRequest
23 голосов
/ 23 апреля 2009

Существует ли команда пакетного обновления в NHibernate? Насколько я знаю, это не так. Итак, как лучше всего справиться с этой ситуацией? Я хотел бы сделать следующее:

  1. Получить список объектов (назовем их списком пользователей, List<User>) из базы данных
  2. Изменить свойства этих объектов, (Users.Foreach(User=>User.Country="Antartica")
  3. Обновлять каждый элемент обратно индивидуально (Users.Foreach(User=>NHibernate.Session.Update(User)).
  4. Позвоните Session.Flush, чтобы обновить базу данных.

Это хороший подход? Приведет ли это к множеству обратных вызовов между моим кодом и базой данных?

Что вы думаете? Или есть более элегантное решение?

Ответы [ 6 ]

41 голосов
/ 17 февраля 2010

Я знаю, что опоздал на вечеринку по этому поводу, но подумал, что вам может быть интересно узнать, что теперь это возможно, используя HQL в NHibernate 2.1 +

session.CreateQuery(@"update Users set Country = 'Antarctica'")
.ExecuteUpdate();
20 голосов
/ 05 апреля 2011

Запуск пакетных заданий NHibernate 3.2 имеет улучшения, сводящие к минимуму циклические обращения к базе данных. Более подробную информацию можно найти в блоге HunabKu . Вот пример из этого - эти пакетные обновления делают только 6 циклов:

using (ISession s = OpenSession())
using (s.BeginTransaction())
{
    for (int i = 0; i < 12; i++)
    {
        var user = new User {UserName = "user-" + i};
        var group = new Group {Name = "group-" + i};
        s.Save(user);
        s.Save(group);
        user.AddMembership(group);
    }
    s.Transaction.Commit();
}
9 голосов
/ 23 апреля 2009

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

<property name="hibernate.adonet.batch_size">16</property>

И вам не нужно вызывать Session.Update (User) там - просто очистите или зафиксируйте транзакцию, и NHibernate справится с вами.

РЕДАКТИРОВАТЬ: Я собирался опубликовать ссылку на соответствующий раздел документов nhibernate, но сайт не работает - вот старая запись из Ayende на эту тему:

Относительно того, является ли использование NHibernate (или любого ORM) здесь хорошим подходом, это зависит от контекста. Если вы выполняете одноразовое обновление каждой строки в большой таблице с одним значением (например, указание для всех пользователей страны «Антарктида» (это, кстати, континент, а не страна!), То вам, вероятно, следует используйте оператор SQL UPDATE. Если вы собираетесь обновлять несколько записей одновременно со страной как часть вашей бизнес-логики при общем использовании вашего приложения, то использование ORM может быть более разумным методом. Это зависит от количества строк, которые вы обновляете каждый раз.

Пожалуй, самый разумный вариант здесь, если вы не уверены, это настроить параметр batch_size в NHibernate и посмотреть, как это работает. Если производительность системы неприемлема, вы можете взглянуть на реализацию простого SQL-оператора UPDATE в своем коде.

6 голосов
/ 01 февраля 2018

Начиная с NHibernate 5.0, можно выполнять массовые операции с использованием LINQ.

session.Query<Cat>()
.Where(c => c.BodyWeight > 20)
.Update(c => new { BodyWeight = c.BodyWeight / 2 });

NHibernate сгенерирует один SQL-запрос на обновление.

См. Обновление сущностей

4 голосов
/ 23 апреля 2009

Вам не нужно ни обновлять, ни очищать:

IList<User> users = session.CreateQuery (...).List<User>;
users.Foreach(u=>u.Country="Antartica")
session.Transaction.Commit();

Я думаю, что NHibernate пишет пакет для всех изменений.

Проблема в том, что ваши пользователи должны быть загружены в память. Если возникает проблема, вы все равно можете использовать собственный SQL с помощью NHibernate. Но пока вы не докажете, что это проблема с производительностью, оставайтесь с хорошим решением.

1 голос
/ 23 апреля 2009

Нет, это не очень хороший подход!

Собственный SQL во много раз лучше для такого рода обновлений.

UPDATE USERS SET COUNTRY = 'Antartica';

Просто не может быть проще, и механизм базы данных будет обрабатывать это в сто раз эффективнее, чем строка за один раз. Java-код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...