2017-05-17 26 views
0

有問題,我的代碼的這一部分與datareader有問題。我遇到了數據採集器

foreach (Giorno iDet in iNom.Gg.Where(x => x.minRegular != 0 | x.minOver != 0 | x.minLate != 0)) 
{ 
    bool Importato = false; 
    com = new SqlCommand("SELECT id, Lavorato, Straordinario, Assenza, Permesso, Malattia, Infortunio, Ferie, Maternita, Ritardo, Festivita " + 
         "FROM presenze_giorno WHERE data = @data AND reparto = @rep AND nomcod = @nom", TranOP.Connection, TranOP); 
    com.Parameters.AddWithValue("data", iDet.Gg); 
    com.Parameters.AddWithValue("rep", iNom.Reparto); 
    com.Parameters.AddWithValue("nom", iNom.Codice);         
    SqlDataReader dr = com.ExecuteReader(); 
    if (dr.HasRows) 
     Importato = true;              
    if (!Importato) 
    { 
     //Inserisco il giorno 
     com = new SqlCommand("INSERT INTO presenze_giorno (data, reparto, nomcod, nomdesc, errmarcatura, ingresso, uscita, " + 
          "Lavorato, Ritardo, Straordinario, Assenza) VALUES " + 
          "(@data, @reparto, @nomcod, @nomdesc, @errmarcatura, @ingresso, @uscita, @Lavorato, @Ritardo, " + 
          "@Straordinario, @Assenza); SELECT SCOPE_IDENTITY()", TranOP.Connection, TranOP); 
     com.Parameters.AddWithValue("data", iDet.Gg); 
     com.Parameters.AddWithValue("reparto", iNom.Reparto); 
     com.Parameters.AddWithValue("nomcod", iNom.Codice); 
     com.Parameters.AddWithValue("nomdesc", iNom.Descrizione); 
     com.Parameters.AddWithValue("errmarcatura", iNom.MarcaturaSbagliata); 
     com.Parameters.AddWithValue("ingresso", iDet.Gg.Add(iDet.InT)); 
     com.Parameters.AddWithValue("uscita", iDet.Gg.Add(iDet.OutT)); 
     com.Parameters.AddWithValue("Lavorato", iDet.minRegular); 
     com.Parameters.AddWithValue("Ritardo", iDet.minLate); 
     com.Parameters.AddWithValue("Straordinario", iDet.minOver); 
     com.Parameters.AddWithValue("Assenza", iDet.minAssente); 
     int wid = Convert.ToInt32(com.ExecuteScalar().ToString()); 
     //Inserisco le marcature 
     Lettura search = Lett.Find(f => f.Data == iDet.Gg & f.Reparto == iNom.Reparto & f.Codice == iNom.Codice); 
     if (search != null) 
      foreach (IngrUsc item in search.IU) 
      { 
       com = new SqlCommand("INSERT INTO presenze_marcature (idtesta, ingresso, uscita) VALUES (@idtesta, @ingresso, @uscita)", TranOP.Connection, TranOP); 
       com.Parameters.AddWithValue("idtesta", wid); 
       com.Parameters.AddWithValue("ingresso", iDet.Gg.Add(item.InT)); 
       com.Parameters.AddWithValue("uscita", iDet.Gg.Add(item.OutT)); 
       com.ExecuteNonQuery(); 
      } 
    }        
    //controllo se tutti gli altri campi sono a 0, se si faccio Update                 
    else if (Convert.ToInt32(dr["Lavorato"]) == 0 & Convert.ToInt32(dr["Straordinario"]) == 0 & Convert.ToInt32(dr["Assenza"]) == 0 & Convert.ToInt32(dr["Permesso"]) == 0 
      & Convert.ToInt32(dr["Malattia"]) == 0 & Convert.ToInt32(dr["Infortunio"]) == 0 & Convert.ToInt32(dr["Ferie"]) == 0 & Convert.ToInt32(dr["Maternita"]) == 0 
      & Convert.ToInt32(dr["Ritardo"]) == 0 & Convert.ToInt32(dr["Festivita"]) == 0) 
    { 
     com = new SqlCommand("UPDATE Presenze_Giorno " + 
          "SET Lavorato = @lav, Straordinario = @stra, Assenza = @ass, Permesso = @perm, Malattia = @mala, Infortunio = @inf, " + 
          "Ferie = @ferie, Maternita = @mat, Ritardo = @rit, Festivita = @fest" + 
          "WHERE data = @data AND reparto = @rep AND nomcod = @nom", TranOP.Connection, TranOP); 
     com.Parameters.AddWithValue("data", iDet.Gg); 
     com.Parameters.AddWithValue("rep", iNom.Reparto); 
     com.Parameters.AddWithValue("nom", iNom.Codice); 
     com.Parameters.AddWithValue("lav", iDet.minRegular); 
     com.Parameters.AddWithValue("stra", iDet.minOver); 
     com.Parameters.AddWithValue("ass", iDet.minAssente); 
     com.Parameters.AddWithValue("perm", iDet.minPermesso); 
     com.Parameters.AddWithValue("mala", iDet.minMalattia); 
     com.Parameters.AddWithValue("inf", iDet.minInfortunio); 
     com.Parameters.AddWithValue("ferie", iDet.minFerie); 
     com.Parameters.AddWithValue("mat", iDet.minMaternita); 
     com.Parameters.AddWithValue("rit", iDet.minLate); 
     com.Parameters.AddWithValue("fest", iDet.minFestivita); 
     com.ExecuteNonQuery(); 
    } 
    dr.Close(); 

當我做否則,如果和嘗試轉換爲int 32博士[「Lavorato」] ECC,ECC給我的錯誤。

「System.InvalidOperationException:「一個命令èGIA ASSOCIATO未 DataReader的Aperto公司,車DEVE essere chiuso。」

+0

Command和DataReader是一次性的,所以應該在'using'語句中。評論而不是答案,因爲我不知道這是否會解決您的問題,但無論如何您都應該這樣做,特別是因爲這是在foreach循環中。 –

+0

你在web config的連接字符串中激活了'MultipleActiveResultSets = true'嗎?看起來你的代碼試圖執行一個查詢,同時仍然迭代另一個查詢的結果(標記錯誤「已經有一個與此命令關聯的打開的DataReader」)。 –

回答

0

DataReader,與其他.NET數據庫類不同,它不與數據庫斷開連接。這意味着它需要開放連接和專用命令。 MSDN指出:

您可以使用ADO.NET DataReader從數據庫中檢索只讀數據流,即 。結果返回爲查詢執行的 ,並存儲在客戶端 的網絡緩衝區中,直到您使用DataReader的Read方法請求它們爲止。

你可以用兩種方式解決問題:

  • 有你的命令的連接字符串中MultipleActiveResultSets=true
  • 具有與數據打交道另一個命令。所以,不是重用com實例,使新的,就像這樣:SqlCommand com2 = new SqlCommand("INSERT INTO presenze_giorno ...

還,另一幾件事情:

不要忘記關閉DataReader釋放資源並緊密結合。最好的辦法是用它using block,就像這樣:

using (SqlDataReader dr = com.ExecuteReader()) 
{ 
    //rest of your code 
} 

和,看起來像你不是要求你的DataReader的Read方法,所以DataReader的沒有進展到第一行和第一行「之前」保持。你可以像這樣:

if (dr.HasRows) 
    Importato = true;  
dr.Read(); 
+0

謝謝尼諾! – frnbrt22

+0

@ frnbrt22標記我的答案作爲解決方案是一種方式來說謝謝:) – Nino