Question

J'utilise actuellement NHibernate. J'ai une situation où je dois sauver un tas d'enregistrements à la base de données comme ceci:

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

Quand il y a une tonne de dossiers pour sauver c'est évidemment très taxant d'avoir à frapper la base de données à plusieurs reprises. Qu'est-ce qu'une meilleure approche? Y at-il une sorte de mise à jour batch que je peux faire? Suis-je mieux d'utiliser un DataSet?

Merci

Était-ce utile?

La solution

mise en adonet.batch_size pourrait améliorer la situation.

Pour que vous avez à

  • set adonet.batch_size dans la configuration NH

Exemple:

    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();
  • définir la taille du lot sur la session juste avant la sauvegarde

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

Autres conseils

Je crois que c'est ce que vous cherchez:

en vrac Sessions Stateless opérations sur les données avec NHibernate

Pour l'essentiel au lieu d'ouvrir un ISession, vous ouvrez un IStatelessSession, et dans votre hibernate.cfg.xml vous pouvez définir:

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

Je pense que vous avez un certain nombre d'options en fonction de votre situation.

Si vous pouvez utiliser NHibernate 2.1 alphas vous pouvez essayer d'utiliser la nouvelle Executable HQL qui est disponible.

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

La réponse de Tobias fonctionnera aussi bien. La seule définition de la taille du lot augmentera la performance respectablement.

Si vous voulez salir les mains avec ADO.Net ...

Faire Inserts en vrac dans Sql Server est possible grâce à l'utilisation de Sql copie en bloc.

Un exemple est ici: http://dotnetslackers.com/articles/ado_net/ SqlBulkCopy_in_ADO_NET_2_0.aspx

Pour moi, il semble que vous créez une nouvelle entité basée hors d'une autre entité dans la base de données. Pour moi, cela semble être un scénario idéal pour utiliser une procédure stockée.

DataSet

? Non. D'insertion en bloc? Oui.

Si vous insérez que de nombreux enregistrements et les inserts sont assez simpliste, vous devriez regarder des insertions en vrac et en tirant le ORM.

La façon la plus rapide pour insérer des enregistrements est de générer un fichier texte et utiliser la syntaxe LOAD FILE. La plupart des bases de données ont mises en œuvre remarquablement rapide à l'importation de fichiers de données dans les bases de données. Pour MySQL, voir ci-dessous:

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

Pour d'autres bases de données, reportez-vous au manuel approprié. Ceci est utile si vous insérez un million de disques, ou des milliers de dossiers fréquemment. Sinon, le mieux que vous pouvez faire est de créer un grand SQL avec le 1000s d'inserts et d'exécuter que sur votre connexion de base de données directement, et leurs ORM sauter connexes validations.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top