foreach DataTable 行 select 在第二列是唯一的

foreach DataTable row select unique at second column

不太确定如何写我的问题..但我在如何为 mysql 编写更新字符串以供以后从 DataTable

中使用时遇到问题

数据:

ID  |  NAME
1   |  SWORD
2   |  SWORD
3   |  SWORD
4   |  SWORD
5   |  HORSE
6   |  SWORD

代码:

using (StreamWriter sw = new StreamWriter(File.Open("update_itemtype_name.txt", FileMode.Create)))
{
    foreach (DataRow row in dt.Rows)
    {
       sw.WriteLine("UPDATE itemtype SET name = '" + row[1] + "' WHERE id >= " + row[0] + " AND id <= " + row[0] + ";");
    }
}

结果:

UPDATE itemtype SET name = 'SWORD' WHERE id >= 1 AND id <= 1;
UPDATE itemtype SET name = 'SWORD' WHERE id >= 2 AND id <= 2;
UPDATE itemtype SET name = 'SWORD' WHERE id >= 3 AND id <= 3;
UPDATE itemtype SET name = 'SWORD' WHERE id >= 4 AND id <= 4;
UPDATE itemtype SET name = 'HORSE' WHERE id >= 5 AND id <= 5;
UPDATE itemtype SET name = 'SWORD' WHERE id >= 6 AND id <= 6;

预期结果:

UPDATE itemtype SET name = 'SWORD' WHERE id >= 1 AND id <= 4;
UPDATE itemtype SET name = 'HORSE' WHERE id >= 5 AND id <= 5;
UPDATE itemtype SET name = 'SWORD' WHERE id >= 6 AND id <= 6;

如何获得预期结果?

您可以使用 LINQ 的 GroupBy,但要做到这一点,您首先需要使用 OfType 方法扩展方法获取数据行的 IEnumerable<DataRow>。另请注意 OrderBy - 为了在您的数据 table 排序不正确的情况下实际获得正确的结果:

var rowGroups = dt.Rows.OfType<DataRow>().OrderBy(r => r["id"]).GroupBy(r => r["Name"]);

foreach(var rowGroup in rowGroups)
{
    var strUpdate = "UPDATE itemtype SET name = '"+ 
                     rowGroup.Key +
                     "' WHERE id >= "+ rowGroup.First()["id"].ToString() + 
                     " AND id <= "+ rowGroup.Last()["id"].ToString();
}

See a live demo on rextester.

但是,这确实有一个缺陷,因为在数据中 table 没有任何东西强迫您将具有相同 Name 值的记录组合在一起按 Id 值。我的意思是,如果您的数据 table 看起来像这样:

1, "SWORD"
2, "SWORD"
3, "SWORD"

4, "KNIFE"
5, "KNIFE"

6, "SWORD"

您将得到这些结果:

UPDATE itemtype SET name = 'SWORD' WHERE id >= 1 AND id <= 6
UPDATE itemtype SET name = 'KNIFE' WHERE id >= 4 AND id <= 5

所以您可能想做一些其他的事情,比如使用 IN 运算符而不是范围检查。这样的事情应该可以解决问题(如果数据中有很多行 table,您应该考虑使用字符串生成器而不是连接):

var rowGroups = dt.Rows.OfType<DataRow>().OrderBy(r => r["id"]).GroupBy(r => r["Name"]);

foreach(var rowGroup in rowGroups)
{
    var strUpdate = "UPDATE itemtype SET name = '"+ rowGroup.Key +"' WHERE id IN(";

    foreach(var row in rowGroup)
    {
        strUpdate += row["id"].ToString() +",";
    }
    strUpdate = strUpdate.TrimEnd(',') +")";
}

See a live demo on rextester.