NHibernate - Нужно изменить порядок сохранения, чтобы удовлетворить ограничения базы данных? - PullRequest
4 голосов
/ 23 сентября 2010

Кто-то из нашей команды по обработке данных добавил ограничение базы данных, и, хотя оно вполне допустимо и желательно, оно создает большие проблемы для NHibernate, потому что, похоже, нет способа переопределить порядок сохранения NHibernate.

Учитывая (глупый пример) класс, подобный этому:

public Person
{  
    public virtual string FirstName { get; set; }  
    public virtual bool IsCurrent { get; set; }  
}

и ограничение на то, что только одна запись в вспомогательной таблице может быть IsCurrent=true одновременно. , .

Если я попытаюсь «объявить устаревшим» существующую запись, установив IsCurrent=false, и заменить ее новой записью на IsCurrent=true, я получу исключение ADO при сохранении, поскольку NHibernate сначала пытается выполнить вставку, нарушая SQL Ограничение сервера, что только одна запись может быть IsCurrent=true одновременно.

Я вижу два варианта:

  1. Можно ли настроить SQL Server для проверки ограничений только в конце транзакции? Следующее утверждение («обновление» старой строки до IsCurrent=false приведет к снятию ограничения.
  2. Может ли порядок сохранения NHibernate (для экземпляров того же типа) быть модифицировали или «намекнули» каким-либо образом?

Спасибо! Джефф

Ответы [ 2 ]

1 голос
/ 23 сентября 2010

Возможен любой подход;Я бы склонился к # 2.Если вы позвоните:

session.saveOrUpdate(person1);
session.flush();
session.saveOrUpdate(person2);

Сброс приведет к отправке оператора SQL в базу данных.Я верю, что это решит вашу проблему.(Выше приведен код Java Hibernate, ваш синтаксис может немного отличаться).

0 голосов
/ 23 сентября 2010

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

В этом конкретном случае я бы использовал анонтерный подход: Там нет проверки целостности. Целостность данных основана на триггере запуска при вставке или обновлении. Триггер отвечает за установку IsCurrent в false для всех соответствующих записей, кроме записи, которая в данный момент вставлена ​​или обновлена. Конечно, вам приходится иметь дело с рекурсивным срабатыванием триггера, так как с помощью триггера вы изменяете записи в той же таблице, где сработал триггер.

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