2009-06-11 10 views
10

Ich verwende derzeit NHibernate. Ich habe eine Situation, wo ich brauche eine Menge von Datensätzen in der Datenbank wie folgt zu speichern:Immer 1000 Datensätze in der Datenbank speichern

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

Wenn es eine Tonne Aufzeichnungen sind diese zu retten ist offensichtlich sehr anstrengend mit der Datenbank, die viele Male getroffen. Was ist ein besserer Ansatz? Gibt es eine Art Batch-Update, das ich machen kann? Bin ich besser dran mit einem DataSet?

Dank

+0

Ich würde David P's Antwort als die Lösung der Frage akzeptieren. –

Antwort

12

Einstellung adonet.batch_size die Situation verbessern könnte.

Dafür müssen Sie

  • Satz adonet.batch_size in der NH-Konfiguration

Beispiel:

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(); 
  • die Stapelgröße auf der Sitzung festgelegt, kurz bevor die Sicherung

    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

Können Sie bitte ein wenig ausarbeiten? – Micah

+1

Warum setzen Sie m_configuration? Ich bekomme immer noch einen Fehler auf SetBatchSize und ich habe versucht herauszufinden, warum. Ich benutze Oracle, vielleicht unterstützt das keine Batch-Größe? –

1

DataSet? Nr. Bulk-Einsatz? Ja.

Wenn Sie so viele Datensätze einfügen und die Inserts sind ziemlich einfach, sollten Sie Bulk-Inserts machen und ziehen Sie das ORM.

+0

Können Sie das etwas genauer ausführen? Ich habe mich noch nie mit Masseneinsätzen beschäftigt. Vielen Dank! – Micah

1

Der schnellste Weg zum Einfügen von Datensätzen besteht darin, eine Textdatei zu generieren und die Syntax LOAD FILE zu verwenden. Die meisten Datenbanken haben bemerkenswert schnelle Implementierungen zum Importieren von Datendateien in die Datenbanken. Für MySQL finden Sie unter:

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

für andere Datenbanken, um entsprechende Handbuch. Dies ist nützlich, wenn Sie häufig eine Million Datensätze oder Tausende von Datensätzen einfügen. Ansonsten ist das Beste, was Sie tun können, ein großes SQL mit den 1000er Einfügungen zu erstellen und das direkt auf Ihrer Datenbankverbindung auszuführen, wobei ORMs und ihre zugehörigen Validierungen übersprungen werden.

3

Ich denke, Sie haben eine Reihe von Optionen abhängig von Ihrer Situation.

Wenn Sie NHibernate 2.1 Alphas verwenden können, können Sie versuchen, die neue ausführbare HQL zu verwenden, die verfügbar ist.

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

Tobias Antwort wird auch funktionieren. Wenn Sie nur die Batch-Größe einstellen, erhöht sich die Leistung respektabel.

Wenn Sie schmutzig wollen Sie Ihre Hände mit ADO.Net ...

Bulk-Einsätze in SQL Server zu tun, ist durch die Verwendung von SQL Bulk Copy.

Ein Beispiel dafür ist hier: http://dotnetslackers.com/articles/ado_net/SqlBulkCopy_in_ADO_NET_2_0.aspx

Für mich scheint es, wie Sie eine neue Einheit aus einer anderen Einheit in der Datenbank basiert Schaffung sind.Für mich scheint das ein ideales Szenario zu sein, um eine gespeicherte Prozedur zu verwenden.

4

Ich glaube, das ist das, was Sie suchen:

Bulk Data Operations With NHibernate's Stateless Sessions

Im Wesentlichen stattdessen eine ISession zu öffnen, öffnen Sie eine IStatelessSession, und in Ihrem hibernate.cfg.xml können Sie einstellen:

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