Как удалить все данные базы данных с помощью NHibernate?

Можно ли удалить все данные в базе данных с помощью NHibernate. Я хочу сделать это перед началом каждого модульного теста. В настоящее время я удаляю свою базу данных и создаю ее снова, но это не приемлемое для меня решение

================================================== ========

Хорошо, вот результаты. Я проверяю это в базе данных (Postgre). Я протестирую CreateSchema(1), решение DanP (2) и решение apollodude217 (3). Я запускаю тесты 5 раз с каждым методом и беру среднее время.

Раунд 1 - 10 тестов
(1) - ~26 сек
(2) - 9,0 сек
(3) - 9,3 сек

Раунд 2 - 100 тестов
(1) - Давай, я не буду делать это на моей машине
(2) - 12,6 сек
(3) - 18,6 с

Я думаю, что нет необходимости тестировать больше тестов.

6 ответов

Решение

Лично я использую хранимую процедуру, чтобы сделать это, но это может быть возможно с исполняемым HQL (см. Этот пост для более подробной информации: http://fabiomaulo.blogspot.com/2009/05/nh21-executable-hql.html)

Нечто в духе сессии. Удаление ("от объекта");

Я использую SchemaExport Класс и воссоздать схему перед каждым тестом. Это почти как удаление базы данных, но это только удаление и воссоздание таблиц. Я предполагаю, что удаление всех данных из каждой таблицы не так быстро, это может быть даже медленнее.

Наши юнит-тесты обычно выполняются на Sqlite в памяти, это очень быстро. Эта база данных существует только до тех пор, пока соединение открыто, поэтому вся база данных создается заново для каждого теста. Мы переключаемся на Sqlserver, изменяя конфигурацию сборки.

Я не утверждаю, что это быстрее, но вы можете сделать что-то подобное для каждого сопоставленного класса:

// untested
var entities = MySession.CreateCriteria(typeof(MappedClass)).List<MappedClass>();
foreach(var entity in entities)
    MySession.Delete(entity);  // please optimize

Это (одно) не будет работать по крайней мере в 2 случаях:

  1. Когда есть данные, которые должны быть в вашей базе данных при запуске приложения.
  2. Если у вас есть тип, в котором несохраненное значение свойства identity равно "any".

Хорошей альтернативой является резервное копирование исходного состояния БД и восстановление его при запуске тестов (это может быть сложным или нет, в зависимости от БД)

Другим решением может быть создание хранимой процедуры, которая стирает данные. В тестовом методе установки или создания экземпляра сначала запустите хранимую процедуру.

Однако я не уверен, что это быстрее, чем любой другой метод, так как мы не знаем размер базы данных и количество строк, которые могут быть удалены. Также я бы не рекомендовал развертывать эту хранимую процедуру на работающем сервере в целях безопасности!

НТН

Повторное создание базы данных является хорошим выбором, особенно для модульного тестирования. Если сценарий создания слишком медленный, вы можете сделать резервную копию базы данных и использовать ее для восстановления БД до исходного состояния перед каждым тестом.

Альтернативой может быть написание скрипта, который удалял бы все внешние ключи в базе данных, а затем удалял / урезал все таблицы. Однако это не приведет к сбросу каких-либо автоматически сгенерированных идентификаторов или последовательностей. Это не похоже на элегантное решение и определенно требует больше времени. В любом случае, это не то, что должно быть сделано через ORM, а не только через NHibernate.

Почему вы отказываетесь от возможности воссоздания? Каковы ваши требования? Схема слишком сложная? Кто-то еще проектирует базу данных? Вы хотите избежать фрагментации файла?

Другие вопросы по тегам