Подтвердить что ты не робот

Пакетное обновление в NHibernate

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

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

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

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

4b9b3361

Ответ 1

Запуск NHBernate 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();
}

Ответ 2

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

session.CreateQuery(@"update Users set Country = 'Antarctica'")
.ExecuteUpdate();

Ответ 3

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

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

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

EDIT: я собираюсь опубликовать ссылку на соответствующий раздел документов nhibernate, но сайт не работает - здесь старое сообщение от Ayende по теме:

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

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

Ответ 4

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

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

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

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

Ответ 5

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

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

UPDATE USERS SET COUNTRY = 'Antartica';

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