Domanda

Sto usando NHibernate attualmente. Ho una situazione in cui ho bisogno di salvare un gruppo di record al database in questo modo:

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 ci sono un sacco di record da salvare questo è ovviamente molto tassare dover colpire il database che molte volte. Che cosa è un approccio migliore? C'è una sorta di aggiornamento batch che posso fare? Sono forse meglio utilizzare un DataSet?

Grazie

È stato utile?

Soluzione

impostazione adonet.batch_size potrebbe migliorare la situazione.

Per questo è necessario

  • impostare adonet.batch_size nella configurazione NH

Esempio:

    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();
  • impostare la dimensione del lotto sulla sessione appena prima del salvataggio

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

Altri suggerimenti

Credo che questo è quello che stai cercando:

Bulk I dati di operazioni con NHibernate Stateless Sessions

In sostanza, invece di aprire un ISession, si apre un IStatelessSession, e nel vostro hibernate.cfg.xml è possibile impostare:

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

Penso che tu abbia un numero di opzioni a seconda della situazione.

Se è possibile utilizzare NHibernate 2.1 alfa si può provare a utilizzare il nuovo eseguibile HQL che è disponibile.

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

La risposta di Tobias funziona altrettanto bene. Basta impostare la dimensione del lotto aumenterà la prestazione rispettabile.

Se si vuole sporcare le mani con ADO.Net ...

Fare Inserti di massa in SQL Server è possibile attraverso l'uso di SQL Copia globale.

Un esempio di ciò è qui: http://dotnetslackers.com/articles/ado_net/ SqlBulkCopy_in_ADO_NET_2_0.aspx

A me sembra che si sta creando una nuova entità in base al largo di un'altra entità nel database. A me questo sembra uno scenario ideale per utilizzare una stored procedure.

DataSet? No. Inserimento di massa? Sì.

Se si sta inserendo che molti record e gli inserti sono piuttosto semplicistico, si dovrebbe guardare a fare inserimenti di massa e tirando fuori l'ORM.

Il modo più veloce per inserire i record è quello di generare un file di testo e utilizzare la sintassi FILE LOAD. La maggior parte dei database hanno implementazioni notevolmente veloci per l'importazione di file di dati nei database. Per MySQL, vedere di seguito:

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

Per altri database, fare riferimento al manuale appropriato. Questo è utile se si sta inserendo un milione di dischi, o migliaia di record di frequente. In caso contrario, il meglio che puoi fare è creare un grande SQL con il 1000s di inserti ed eseguire che sulla vostra connessione di database direttamente, ORM saltare e le loro convalide correlati.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top