C#循环问题

时间:2010-09-08 17:30:24

标签: c# asp.net

以下是我的代码:

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,但每个循环不会改变。

5 个答案:

答案 0 :(得分:1)

我同意其他人的困惑,但这里有一个观察结果:将Update和Insert逻辑建立在存在一些现有数据的事实上可能不是一个好主意。如果CSV包含一个新行和一行要更新怎么办?如果现有数据与CSV中的数据完全不重叠怎么办?

你可能希望有像Alvin提到的那样的逻辑,它从行中提取ID。之后,检查数据库中是否存在ID,并使用结果确定它是插入还是更新。

答案 1 :(得分: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的参数,而不是一长列值数据类型。更易于维护!

请注意,MyDTO将OriginalID作为属性,并检查其是否存在已内置于Select

Here's a sample on PasteBin。确保您是using System.Linq;

答案 2 :(得分:0)

什么是GetActiveServiceKeys? 你不应该试图从行[]上下文中提取该ID吗?

答案 3 :(得分:0)

这一行var originalID = Convert.ToInt32(GetActiveServiceKeys.Rows[ ["ActiveServiceKeysID"]);并没有多大意义。我从中推断出你要做的是将foreach循环的当前迭代行与GetActiveServiceKeys表中的特定行匹配,然后获取ActiveServiceKeysID列的值这样您就可以将它用于更新声明。

以下是需要考虑的一些要点:

  1. 根据上传文件中当前行的值,您需要一种方法在GetActiveServiceKeys表中查找相应的行。理想情况下,您在上传的文件中指定了某种唯一键。没有这样的钥匙吗?我假设上传的文件中没有ActiveServiceKeysID值,否则您可以直接使用它而无需从其他表中查找。是否还有其他一组字段可用于唯一标识行?如果没有,那么在单行上执行简单更新可能是不可能的。

  2. 上传的文件是否可以混合使用现有行以及要插入的新行?在您当前的代码中,您基本上根据数据库中是否已有行来决定您是处于“插入”模式还是“更新”模式。我更愿意单独处理每一行,并检查GetActiveServiceKeys表是否包含与该行匹配的行。

  3. 另一种方法是简单地清除当前数据库的ActiveServiceKeys表,并将其替换为上传文件的内容。

答案 4 :(得分:0)

我和p.campbell一起工作过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++;
                 }