2009-06-11 10 views
10

Actualmente estoy usando NHibernate. Tengo una situación donde tengo que guardar un montón de registros a la base de datos de esta manera:Guardando más de 1000 registros en la base de datos a la vez

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); 
} 

Cuando hay un montón de registros para guardar esta es, obviamente, muy exigente tener que golpear la base de datos que muchas veces. ¿Cuál es un mejor enfoque? ¿Hay algún tipo de actualización por lotes que pueda hacer? ¿Sería mejor utilizar un DataSet?

Gracias

+0

Acepto la respuesta de David P como la solución a la pregunta. –

Respuesta

12

establecer adonet.batch_size podrían mejorar la situación.

Para que usted tiene que

  • conjunto adonet.batch_size en la configuración NH

Ejemplo:

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(); 
  • ajustar el tamaño de lote en la sesión justo antes el guardado

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

¿Puedes elaborar un poco por favor? – Micah

+1

¿Por qué configuras m_configuration? Recibo un error todavía en SetBatchSize y estaba tratando de descubrir por qué. Estoy usando Oracle, ¿quizás no es compatible con el tamaño del lote? –

1

DataSet? No. Bulk Insert? Sí.

Si está insertando muchos registros y las inserciones son bastante simples, debería ver hacer Inserciones masivas y extraer el ORM.

+0

¿Puedes dar más detalles sobre eso? Nunca he tratado con inserciones masivas antes. ¡Gracias! – Micah

1

La forma más rápida de insertar registros es generar un archivo de texto y usar la sintaxis LOAD FILE. La mayoría de las bases de datos tienen implementaciones notablemente rápidas para importar archivos de datos en las bases de datos. Para MySQL, ver más abajo:

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

Para otras bases de datos, consulte el manual apropiado. Esto es útil si está insertando un millón de registros, o miles de registros con frecuencia. De lo contrario, lo mejor que puede hacer es crear un gran SQL con los miles de insertos y ejecutarlo en su conexión de base de datos directamente, omitiendo los ORM y sus validaciones relacionadas.

3

Creo que tiene una serie de opciones dependiendo de su situación.

Si puede utilizar NHibernate 2.1 alphas puede intentar utilizar el nuevo HQL ejecutable que está disponible.

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

respuesta de Tobias funcionará tan bien. Simplemente establecer el tamaño del lote aumentará el rendimiento respetablemente.

Si desea ensuciar las manos con ADO.Net ...

se hacen inserciones masiva en SQL Server es posible mediante el uso de SQL copia masiva.

Un ejemplo de esto es aquí: http://dotnetslackers.com/articles/ado_net/SqlBulkCopy_in_ADO_NET_2_0.aspx

A mí me parece que va a crear una nueva entidad con sede fuera de otra entidad en la base de datos.Para mí, parece un escenario ideal para usar un procedimiento almacenado.

Cuestiones relacionadas