2012-07-05 12 views
16

Sto cercando di inserire una grande raccolta di oggetti in una tabella utilizzando NHibernate fluente, utilizzando una chiamata per salvare o aggiornare passando ogni entità dalla raccolta in un ciclo foreach. Avevo impostato la dimensione del batch in base alle dimensioni della raccolta, tuttavia ho letto sul blog di Ayende che non è consigliabile impostarlo su valori elevati, quindi l'ho limitato a 250, tuttavia quando visualizzo la raccolta in NHProf, I vedere un flusso di istruzioni di inserimento (la raccolta è di circa 20000 articoli) anziché un insieme di chiamate di inserimento in batch.Inserimento di una raccolta di entità in blocco utilizzando Fluent NHibernate

Questo sembra molto inefficiente e richiede molto più tempo di quanto mi aspetterei per una query che è essenzialmente di base - inserire un valore in 25 colonne (sì, quello è un posto che potrebbe essere migliorato, ma è un database legacy con cui sono bloccato per ora) in un database di SQL Server 2008, quindi posso solo presumere che stia sbagliando.

Esiste un modo consigliato per inserire grandi raccolte di entità utilizzando NHibernate? C'è un guadagno in termini di efficienza usando Save su SaveOrUpdate?

Codice del metodo add - la chiamata SetBatchSize è dove il lotto è limitato a 250, o impostare la dimensione raccolta se è inferiore a 250:

public void Add(IEnumerable<TEntity> entities) 
{ 
    var session = GetCurrentSession(); 
    using (var transaction = session.BeginTransaction()) 
    { 
     entities = entities.ToList(); 

     session.SetBatchSize(SetBatchSize(entities.Count())); 

     foreach (var entity in entities) 
      session.SaveOrUpdate(entity); 

     transaction.Commit(); 
    } 
} 

Ci scusiamo per la domanda un po 'vaga, ottengo la sensazione che mi sto avvicinando alle cose nel modo sbagliato e ogni suggerimento sarebbe molto apprezzato!

risposta

3

Si desidera utilizzare una StatelessSession per inserimenti di massa.

(correlato: Inserts of stateless session of NHibernate are slow)

+1

Grazie, ho guardato il link e anche cambiato sopra l'inserto di utilizzare una sessione senza stato, e non è fatta alcuna differenza davvero. Parte del problema è che questa è un'app brownfield e non ho la possibilità di generare un'identità. C'è un modo per forzare l'NH a eseguire un inserimento senza richiedere l'identità dell'ambito quando inserisce un record? –

+1

Disclaimer: c'è un modo per fare in modo che NHibernate faccia tutto quello che vuoi. Ma - in questo caso, non puoi cambiare il tuo modello. Direi che l'NH non è lo strumento adatto in questo caso. – hometoast

+1

Grazie, è una specie di conclusione a cui sono arrivato. Ho chiesto specificamente l'identità dell'oscilloscopio in un'altra domanda, nel caso in cui qualcuno conosca qualche forma di magia che posso usare. –

Problemi correlati