Pergunta

Eu estou usando NHibernate atualmente. Eu tenho uma situação onde eu preciso para salvar um monte de registros no banco de dados como este:

var relatedTopics = GetRelatedTopics(topic);
foreach (var relatedTopic in relatedTopics /* could be anywhere from 10 - 1000+ */)
{
    var newRelatedTopic = new RelatedTopic { RelatedTopicUrl = relatedTopic, TopicUrl = topic.Name };
    _repository.Save(newRelatedTopic);
}

Quando há uma tonelada de registros para salvar este é, obviamente, muito desgastante ter que bater o banco de dados que muitas vezes. O que é uma abordagem melhor? Existe algum tipo de atualização em lote que posso fazer? Am I melhor usar um DataSet?

Graças

Foi útil?

Solução

ajuste adonet.batch_size poderia melhorar a situação.

Por que você tem que

  • adonet.batch_size conjunto na configuração NH

Exemplo:

    m_sessionFactory = Fluently
         .Configure()
         .Database(MsSqlConfiguration
             .MsSql2005
             .ConnectionString(c => c.FromConnectionStringWithKey("testme"))
             )
         .Mappings(m => m.FluentMappings
             .AddFromAssemblyOf<TestImpl>())
         .ExposeConfiguration(config =>
         {
             config.SetProperty("adonet.batch_size", "1");
             m_configuration = config;
         })
         .BuildSessionFactory();
  • definir o tamanho do lote na sessão pouco antes da save

    using (ISession session = m_nhibernateSessionFactory.GetSession())
    using (var tx = session.BeginTransaction())
    {    
       session.SetBatchSize(1000);     
       foreach (var server in serverz)
       {
          session.SaveOrUpdate(server);
       }
       tx.Commit();
    }
    

Outras dicas

Eu acredito que este é o que você está procurando:

massa Stateless Sessões de dados operações com NHibernate

Essencialmente em vez de abrir um ISession, você abre um IStatelessSession, e em sua hibernate.cfg.xml é possível definir:

 <property name="adonet.batch_size">100</property>

Eu acho que você tem um número de opções, dependendo da sua situação.

Se você pode usar NHibernate 2.1 alfas você pode tentar usar o novo executável HQL que está disponível.

http://nhibernate.info/blog /2009/05/05/nh2-1-executable-hql.html

A resposta de Tobias vai funcionar tão bem. Apenas definir o tamanho do lote irá aumentar o desempenho respeitável.

Se você quiser sujar as suas mãos com ADO.Net ...

Fazendo inserções em massa no SQL Server é possível através do uso de Sql de cópia em massa.

Um exemplo de que é aqui: http://dotnetslackers.com/articles/ado_net/ SqlBulkCopy_in_ADO_NET_2_0.aspx

Para mim parece que você está criando uma nova entidade baseado fora de outra entidade do banco de dados. Para mim, isso parece ser um cenário ideal para usar um procedimento armazenado.

DataSet? Não. Inserção em massa? Sim.

Se você estiver inserindo que muitos registros e as inserções são muito simplista, você deve olhar para fazer massa Insere e puxar o ORM.

A maneira mais rápida para inserir registros é gerar um arquivo de texto e sintaxe uso carregar o arquivo. A maioria dos bancos de dados têm implementações notavelmente rápidas para a importação de arquivos de dados em bancos de dados. Para o MySQL, veja abaixo:

http://dev.mysql.com/doc /refman/5.1/en/load-data.html

Para outros bancos de dados, consulte a apropriar manual. Isso é útil se você está inserindo um milhão de discos, ou milhares de registros de frequência. Caso contrário, o melhor que você pode fazer é criar uma grande SQL com as 1000s de inserções e executar que na sua conexão de banco de dados diretamente, ignorando ORMs e suas validações relacionados.

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