Pergunta

É possível apagar todos os dados no banco de dados usando o NHibernate.Eu quero fazer isso antes de iniciar cada teste de unidade.Atualmente eu largar o meu banco de dados e crie-o novamente, mas isso não é solução aceitável para mim.

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

Ok, aqui estão os resultados.Eu estou testando isso em um banco de dados (Postgre).Vou testar CreateSchema(1), DanP solução de(2) e apollodude217 solução de(3).Eu executar os testes 5 vezes com cada método e tomar o tempo médio.

Rodada 1 - 10 testes
(1) - ~26 sec
(2) - 9,0 sec
(3) - 9,3 sec

Round 2 - 100 testes
(1) - Venha, eu não vou fazer isso na minha máquina
(2) - 12,6 sec
(3) - 18,6 sec

Eu acho que não é necessário testar com mais testes.

Foi útil?

Solução

Pessoalmente, eu uso um procedimento armazenado para fazer isso, mas pode ser possível com o HQL executável (consulte este post para mais detalhes: http://fabiomaulo.blogspot.com/2009/05/NH21-Executable-hql.html )

algo ao longo das linhas de sessão.Delete ("do objeto");

Outras dicas

Eu estou usando o SchemaExport classe e recriar o esquema antes de cada teste.Isso é quase como descartar o banco de dados, mas é só largar e recriar as tabelas.Eu suponho que a exclusão de todos os dados de cada tabela não é mais rápido do que isto, ele poderia até mesmo ser mais lento.

Nossos testes de unidade são geralmente executado em Sqlite na memória, isso é muito rápido.Este banco de dados existe apenas enquanto a conexão está aberta, para todo o banco de dados é recriada para cada teste.Estamos a mudar para Sqlserver alterando a configuração de compilação.

Não tenho a pretensão de que este é mais rápido, mas você pode fazer algo como isso para cada classe mapeada:

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

Este (sozinho) vai não trabalho em pelo menos 2 casos:

  1. Quando não há dados que devem ser no seu banco de dados quando o aplicativo é iniciado.
  2. Quando você tem um tipo, em que a identidade da propriedade unsaved-value é "qualquer um".

Uma boa alternativa é ter um backup do estado inicial do banco de dados e restaurá-lo ao iniciar os testes (isso pode ser complexo ou não, dependendo do dB)

Recriando o banco de dados é uma boa escolha, especialmente para testes unitários.Se o script de criação for muito lento, você poderá fazer um backup do banco de dados e usá-lo para restaurar o banco de dados para um estado inicial antes de cada teste.

A alternativa seria escrever um script que soltaria todas as chaves estrangeiras no banco de dados e depois excluir / truncar todas as tabelas.Isso não redefundaria quaisquer IDs ou seqüências autogenerados no entanto.Isso não parece uma solução elegante e é definitivamente mais demorado. Em qualquer caso, isso não é algo que deve ser feito através de um orm, não apenas nhibernate.

Por que você rejeita a opção de re-criação?Quais são suas necessidades?O esquema é muito complexo?Alguém mais projetam o banco de dados?Você quer evitar fragmentação de arquivos?

Outra solução pode ser criar um procedimento armazenado que limpa os dados.Em seu teste configurado ou método instanciar, execute primeiro o procedimento armazenado.

No entanto, não tenho certeza se isso é mais rápido que qualquer um dos outros métodos, pois não sabemos o tamanho do banco de dados e o número de linhas prováveis a serem excluídas.Também não recomendaria implantar este procedimento armazenado para o servidor ao vivo para fins de segurança!

hth

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top