2010-09-08 42 views
0

下面是我的代碼:C#環流式問題

protected void SubmitCSV_Click(object sender, ImageClickEventArgs e) 
    { //Check Routes File Uploader for file 
     if (ImportCSV.HasFile) 
     { 
      //Get File name 
      string fileName = ImportCSV.FileName; 
      //Read CSV 
      StreamReader ReadUploadedFile = new StreamReader(ImportCSV.FileContent); 
      //Parse CSV 
      var pathOfCSVFile = ReadUploadedFile; 
      //Gather CSV contents 
      var adapter = new GenericParsing.GenericParserAdapter(pathOfCSVFile); 
      //Ignore first row 
      adapter.FirstRowHasHeader = true; 

    DataTable TempRouteDataTable = adapter.GetDataTable(); 

if (ExcelDDL.SelectedValue == "Active Service Keys" && fileName == "ActiveServiceKeys.csv") 
    { 
    SEPTA_DS.ActiveServiceKeysTBLDataTable GetActiveServiceKeys = (SEPTA_DS.ActiveServiceKeysTBLDataTable)askta.GetData(); 
    var hasData = GetActiveServiceKeys.Rows.Count > 0; 

    //Loop through each row and insert into database 
    foreach (DataRow row in TempRouteDataTable.Rows) 
      { 
       //Gather column headers 
       var category = Convert.ToString(CategoryDDL.SelectedItem); 
       var agency = Convert.ToString(row["Agency"]); 
       var route = Convert.ToString(row["Route"]); 
       var direction = Convert.ToString(row["Direction"]); 
       var serviceKey = Convert.ToString(row["Service Key"]); 
       var language = Convert.ToString(row["Language"]); 
       var activeServiceKeys = Convert.ToString(row["Active Service Keys"]); 

       //Check if data already exists 
       if (hasData == true) 
       { 
       var originalID = Convert.ToInt32(GetActiveServiceKeys.Rows[0] ["ActiveServiceKeysID"]); 
       int updateData = Convert.ToInt32(askta.UpdateActiveServiceKeys(category, agency, route, direction, serviceKey, language, activeServiceKeys, originalID)); 
       } 
       else 
       { 
       int insertData = Convert.ToInt32(askta.InsertActiveServiceKeys(category, agency, route, direction, serviceKey, language, activeServiceKeys)); 
       } 
      } 
      } 
    } 
} 

問題存在的行之後發生。 foreach目前正在讀取上傳的CSV文件,因此在啓動foreach時,它將一行放入數據庫中。

編輯:

數據時不我想運行insert方法存在數據庫中。 當它存在時,我想運行update方法。

問題:運行update方法時,需要使用originalID(自動遞增int)。由於上傳CSV的每行都在foreach以內,所以我不熟悉如何獲取每個循環的originalID

目前,(只是固定)我有一個0,但不會改變每個循環。

+3

你已經發布了很多代碼,但你的問題不是很清楚。你說你「拿不到原始身份證」 - 你的意思是什麼? – 2010-09-08 17:33:39

+0

額外的方括號是否爲錯字? 'GetActiveServiceKeys.Rows [[「ActiveServiceKeysID」]' – Greg 2010-09-08 17:36:44

+0

目前尚不清楚你爲什麼需要原始ID。代碼是更新或插入。對於同一組數據,是否有許多行,您需要「記住」或查找現有的ID? – 2010-09-08 17:40:50

回答

0

我p.campbell合作USS LINQ,但我遇到了太多錯誤,但我相信,如果我有我可以得到它的工作更多的時間。

我用這種方法,它似乎工作。它會檢查項目是否存在,如果存在,它會更新,如果不存在則添加它。

//Loop through each row and insert into database 
       int i = 0; 
       foreach (DataRow row in TempRouteDataTable.Rows) 
       { 
        //Gather column headers 
        var category = Convert.ToString(CategoryDDL.SelectedItem); 
        var agency = Convert.ToString(row["Agency"]); 
        var route = Convert.ToString(row["Route"]); 
        var direction = Convert.ToString(row["Direction"]); 
        var serviceKey = Convert.ToString(row["Service Key"]); 
        var language = Convert.ToString(row["Language"]); 
        var activeServiceKeys = Convert.ToString(row["Active Service Keys"]); 
        var origID = -1; 

        if (GetActiveServiceKeys.Rows.Count > 0) 
        { 
         origID = Convert.ToInt32(GetActiveServiceKeys.Rows[i]["ActiveServiceKeysID"]); 
         var GetID = (SEPTA_DS.ActiveServiceKeysTBLDataTable)askta.GetDataByID(origID); 
         if (GetID.Rows.Count < 1) 
         { 
          origID = -1; 
         } 
        } 

        if (origID == -1) 
        { 
         int insertData = Convert.ToInt32(askta.InsertActiveServiceKeys(category, agency, route, direction, serviceKey, language, activeServiceKeys)); 
        } 
        else 
        { 
         int updateData = Convert.ToInt32(askta.UpdateActiveServiceKeys(category, agency, route, direction, serviceKey, language, activeServiceKeys, origID)); 
        } 
        i++; 
       } 
0

什麼是GetActiveServiceKeys? 不應該試圖從行[]上下文中獲取該ID?

1

我分享了其他人的困惑,但是這裏有一個觀察:根據存在一些現有數據的事實,將更新vs插入邏輯基於它可能不是一個好主意。如果CSV包含一個新行和一行更新,該怎麼辦?如果現有數據與CSV中的數據完全不重疊,該怎麼辦?

你可能希望有像Alvin提到的邏輯,它從行中拉出ID。之後,檢查ID是否已存在於數據庫中,並使用結果來確定它是插入還是更新。

1

考慮重構代碼以使用LINQ和麪向對象的解決方案。這會讓讀起來更容易&保持!

創建一個類來鏡像您的數據表的行。在這裏,我把它叫做MyDTO

foreach (var item in dt.Rows.Cast<DataRow>().Select(r=> new MyDTO {     
      category = CategoryDDL.SelectedItem.ToString(), 
      agency = r["Agency"].ToString(), 
      route =  r["Route"].ToString(), 
      direction = r["Direction"].ToString(), 
      serviceKey= r["Service Key"].ToString(), 
      language = r["Language"].ToString(), 
      originalID = GetActiveServiceKeys.Rows[r["Active Service Keys"].ToString()] 
      activeServiceKeys = r["Active Service Keys"].ToString()} 
     )) 
     { 
     if (!string.IsNullOrEmpty(item.originalID))    
      int updateData = askta.UpdateActiveServiceKeys(item); 
     else 
      int insertData = askta.InsertActiveServiceKeys(item); 
     } 

這就要求您更改接口askta方法InsertActiveServiceKeysUpdateActiveServiceKeys()採取MyDTO類型,而不是價值的數據類型一長串的PARAM。更容易維護!

請注意,MyDTO具有OriginalID作爲屬性,並檢查它是否存在正在構建到Select

Here's a sample on PasteBin。確保你是using System.Linq;

+0

嗯......我不熟悉LINQ。這段代碼是否拖放? – balexander 2010-09-08 18:28:53

+0

@ Bry4n:你打賭;只需要讓你自己創建新的MyDTO類。還要確保你的2'askta'方法實際返回一個整數。你必須確保'GetActiveServiceKeys.Rows'位是正確的。 – 2010-09-08 18:54:33

+0

@ p.campbell'dt'需要更改爲'TempRouteDataTable'不是嗎? – balexander 2010-09-08 19:23:44

0

這條線var originalID = Convert.ToInt32(GetActiveServiceKeys.Rows[ ["ActiveServiceKeysID"]);並沒有什麼意義。我從中推斷出你要做的是將你的foreach循環的當前迭代的行與GetActiveServiceKeys表中的特定行進行匹配,然後獲得ActiveServiceKeysID列的值,以便您可以將它用於您的更新聲明。

這裏有幾點考慮:

  1. 您需要一種方法來找出給定的上傳文件中的當前行的值GetActiveServiceKeys表中的相應行。理想情況下,您會在上傳的文件中指定某種唯一的密鑰。有沒有這樣的鑰匙?我假設在上傳的文件中沒有ActiveServiceKeysID值,否則你可以直接使用它,而不必從另一個表中查找它。是否有任何其他字段可用於唯一標識一行?如果沒有,那麼對單行進行簡單更新可能不會成功。

  2. 上傳的文件是否可以混合使用現有行進行更新以及插入新行?在您當前的代碼中,您基本上根據數據庫中是否存在行來決定是處於「插入」模式還是「更新」模式。我寧願單獨處理每行,並檢查GetActiveServiceKeys表是否包含與該行匹配的行。

  3. 另一種方法是簡單地清除當前數據庫的ActiveServiceKeys表並將其替換爲上載文件的內容。