使用foreach时如何检查DataTable行是否已更改?

时间:2012-09-19 15:10:16

标签: c# datatable .net-2.0

我有以下代码:

int sequence = 1; //This is incremented every time the Account changes
int numberOfItems; //This is reset after the Account changes
decimal totalAmount = 0m; //This is reset after the Account changes
string prevRow; //not sure how to handle this

foreach(DataRow row in dt.Rows)
{
  //I am stuck here
  if(row["Account"]) == prevRow)
  {
  numberOfItems++;
  totalAmount += Convert.ToDecimal(row["TotalAmount"]);
  }
  else
  {
     //reset everything and increase sequence
     numberOfItems = 0;
     totalAmount = 0m;
     sequence++
  }

}

我的初始表可能包含以下数据:

abc,50.0
abc,50.0
def,60.0
ghi,70.0

当使用for循环时,abc的numberOfItems应该为2,对于def为1,对于ghi为1。 abc的totalAmount应为100.0,def为60.0,ghi为70.0。对于abc,序列应为1,对于def,序列应为2,对于ghi,序列应为3。

在运行for循环时我注意到的第一件事是它在第一个表中跳过了一堆行,所以当我在else中创建第二个表时,numberOfItems和totalAmount仍然是0.第二个表应该是某个东西像:

abc,100,2,1 def,60,1,2 ghi,70,1,3

其中csv值中的最后一个数字是序列,而之前的数字是每个帐户的numberOfItems。

for (int i = 0; i < dt.Rows.Count; i++ )
            {
                DataRow row = dt.Rows[i];
                DataRow prevRow = i > 0 ? dt.Rows[i - 1] : null;

                if (prevRow != null && row[1] == prevRow[1])
                {
                    numberOfItems++;
                    totalAmount += Convert.ToDecimal(row[2]);
                    row[3] = "D";
                    row[4] = c;
                    row[5] = sequence;

                }
                else
                {
                    dt2.Rows.Add("N",
                        c,
                        row[1],
                        row[2],
                        row[3],
                        numberOfItems,
                        totalAmount,
                        sequence);

                    numberOfItems = 0;
                    totalAmount = 0m;
                    sequence++;
                }
            }

4 个答案:

答案 0 :(得分:1)

您可以使用DataTable.GetChanges

链接:http://msdn.microsoft.com/en-us/library/k2552649.aspx

var changeTable = table.GetChanges();
foreach(var item in changeTable.Rows)
{
 .....

}

对于修改过的行,您可以使用参数DataRowState.Modified

table.GetChanges(DataRowState.Modified);

答案 1 :(得分:0)

int sequence = 1; //This is incremented every time the Account changes
int numberOfItems; //This is reset after the Account changes
decimal totalAmount = 0m; //This is reset after the Account changes
string prevRow = null; //not sure how to handle this

foreach(DataRow row in dt.Rows)
{
  //I am stuck here
  if((row["Account"]) == prevRow)
  {
  numberOfItems++;
  totalAmount += Convert.ToDecimal(row["TotalAmount"]);
  }
  else
  {
     //reset everything and increase sequence
     numberOfItems = 0;
     totalAmount = 0m;
     sequence++;
  }
  prevRow = row["Account"];

}

请注意,我已经放了一个;在序列递增之后。

答案 2 :(得分:0)

int sequence = 1; //This is incremented every time the Account changes
int numberOfItems; //This is reset after the Account changes
decimal totalAmount = 0m; //This is reset after the Account changes
String prevAccount == ""; //not sure how to handle this

foreach(DataRow row in dt.Rows)
{
   //I am stuck here
   if(row["Account"] == prevAccount)
   {
      numberOfItems++;
      totalAmount += Convert.ToDecimal(row["TotalAmount"]);
   }
   else
   {
       //reset everything and increase sequence
       numberOfItems = 0;
       totalAmount = 0m;
       sequence++;
    }
    prevAccount = row["Account"];
}

答案 3 :(得分:0)

foreach行不知道它的前一行。那你为什么不简单地使用for-loop

for(int i = 0; i < dt.Rows.Count; i++)
{
    DataRow row = dt.Rows[ i ];
    DataRow prevRow = i > 0 ? dt.Rows[ i - 1 ] : null;

    if(prevRow != null && row["Account"] == prevRow["Account"])
    {
        // ...
    }
} 

现在您已更新了我的问题,我建议您使用Linq-To-DataSet

var groups = dt.AsEnumerable()
    .GroupBy(r => r.Field<String>("Account"))
    .Select((g, i) => new { 
        Account = g.Key,
        TotalAmount = g.Sum(r => r.Field<double>("TotalAmount")),
        Count = g.Count(),
        Id = i + 1,
    });

foreach (var grp in groups)
    Console.WriteLine("{0},{1},{2},{3}"
        ,grp.Account, grp.TotalAmount, grp.Count, grp.Id);

请注意,您需要添加using System.Linq