2010-08-21 5 views
1

c'est mon code que j'ai:Exécuter des insertions SQLite dans plusieurs boucles foreach en C#?

J'ai lu que la configuration du CommandText ne devrait se produire qu'une seule fois et non pas en boucle ... mais comment puis-je obtenir les données de chaque élément de la foreach?

Quelqu'un assez intelligent pour factoriser ce code, ce serait bien :)

using (SQLiteTransaction trans = DataAccess.ConnectionManager.BeginTransaction()) 
{ 
    using (SQLiteCommand com = new SQLiteCommand(DataAccess.ConnectionManager)) 
    { 
     // How can I add the parameters here if they are only known in the foreach loop? 
     com.Parameters.Add(new SQLiteParameter("@date", day.SchooldayDate)); 
     com.Parameters.Add(new SQLiteParameter("@periodnumber", period.PeriodNumber)); 
     com.Parameters.Add(new SQLiteParameter("@schoolclasscode", period.SchoolclassCode)); 


     foreach (var week in weekList) 
     { 
      foreach (var day in week.Days) 
      { 
       foreach (var period in day.Periods) 
       { 
        com.CommandText = "Insert into tablename (date,periodnumber,schoolclasscode) Values (@date,@periodnumber,@schoolclasscode)"; 

       } 
      } 
     } 

     com.ExecuteNonQuery(); 
    } 
    trans.Commit();     
} 

MISE À JOUR: La solution qui fonctionne!

using (SQLiteTransaction trans = DataAccess.ConnectionManager.BeginTransaction()) 
      { 
       using (SQLiteCommand com = new SQLiteCommand(DataAccess.ConnectionManager)) 
       { 
        com.CommandText = "Insert into lessonday (lessondate,lessonnumber,schoolclasscode) VALUES (@lessondate,@lessonnumber,@schoolclasscode)"; 

        SQLiteParameter p1 = new SQLiteParameter("@lessondate", DbType.DateTime); 
        SQLiteParameter p2 = new SQLiteParameter("@lessonnumber", DbType.Int32); 
        SQLiteParameter p3 = new SQLiteParameter("@schoolclasscode", DbType.String); 

        com.Parameters.Add(p1); 
        com.Parameters.Add(p2); 
        com.Parameters.Add(p3); 

        foreach (var week in weekList) 
        { 
         foreach (var day in week.Days) 
         { 
          p1.Value = day.SchooldayDate; 
          foreach (var period in day.Periods) 
          { 
           p2.Value = period.PeriodNumber; 
           p3.Value = period.SchooclassCode; 

           com.ExecuteNonQuery(); 
          } 
         } 
        } 
       } 
       trans.Commit(); 
      } 
     } 
+0

Ouais, c'est la bonne façon de le faire !! L'utilisation de requêtes paramétrées et le regroupement de vos insertions en une seule transaction importante rendent Sqlite beaucoup plus rapide. – TTT

+0

oui c'était terrible rapide 4000 insérer en moins d'une seconde feutre :) – Elisabeth

+0

il était encore plus fou en 0,488 secondes inséré 40K rangées avec 5 colonnes haha. Sqlite est fou rapide. – Elisabeth

Répondre

0

Eh bien, vous pouvez simplement déplacer les boucles:

using (SQLiteTransaction trans = DataAccess.ConnectionManager.BeginTransaction()) 
{ 
    foreach (var week in weekList) 
    { 
    foreach (var day in week.Days) 
    { 
     foreach (var period in day.Periods) 
     { 
     using (SQLiteCommand com = new SQLiteCommand(...)) 
     { 
      com.Parameters.Add(new SQLiteParameter(...)); 
      com.Parameters.Add(new SQLiteParameter(...)); 
      com.Parameters.Add(new SQLiteParameter(...)); 
      com.CommandText = "Insert into ..."; 
      com.ExecuteNonQuery(); 
     } 
     } 
    } 
    } 
    trans.Commit();     
} 

Cependant, cela me semble un peu laid. Je ne sais pas comment le fournisseur SQLite va se comporter, mais je pense qu'il serait au moins essayer pour créer le SQLiteCommand selon votre code d'origine, en ajoutant les paramètres mais pas leurs valeurs ... puis en déplaçant le Code ExecuteNonQuery dans la boucle foreach la plus interne. Quelque chose comme ceci:

using (SQLiteTransaction trans = DataAccess.ConnectionManager.BeginTransaction()) 
{ 
    using (SQLiteCommand com = new SQLiteCommand(DataAccess.ConnectionManager)) 
    { 
    com.CommandText = "Insert into ..."; 
    SQLiteParameter p1 = com.Parameters.Add(new SQLiteParameter(...)); 
    SQLiteParameter p2 = com.Parameters.Add(new SQLiteParameter(...)); 
    SQLiteParameter p3 = com.Parameters.Add(new SQLiteParameter(...)); 
    foreach (var week in weekList) 
    { 
     p1.Value = week; 
     foreach (var day in week.Days) 
     { 
     p2.Value = day; 
     foreach (var period in day.Periods) 
     { 
      p3.Value = period;    
      com.ExecuteNonQuery(); 
     } 
     } 
    } 
    } 
    trans.Commit();     
} 

Je répète, je ne sais pas si cela va fonctionner - mais je espoir ce serait.

+0

[+1 si je pouvais!] (Http://meta.stackexchange.com/questions/5212/) – Timwi

+0

@Lisa: Je suppose que c'est le mauvais type. Essayez de créer les paramètres avec le DbType approprié. –

+0

oui juste fait avant que vous posté ce et j'ai enlevé mon commentaire HAHA voir mis à jour à nouveau: P OK merci Jon maintenant je peux aller dormir bonne nuit;) – Elisabeth

Questions connexes