foreach DataTable行在第二列中选择唯一

时间:2018-02-14 09:34:09

标签: c# foreach datatable datarow

我不确定如何编写我的问题..但我在如何为mysql编写UPDATE字符串以便以后从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;

我如何得到预期的结果?

1 个答案:

答案 0 :(得分:1)

您可以使用LINQ的GroupBy,但要做到这一点,首先需要使用IEnumerable<DataRow>方法扩展方法获取OfType数据行。另请注意OrderBy - 以便在数据表未正确订购时实际获得正确的结果:

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.

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

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运算符而不是范围检查。这样的事情可以解决问题(如果数据表中有很多行,你应该考虑使用字符串生成器而不是连接):

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.