【问题标题】:Update DataTable using LINQ使用 LINQ 更新数据表
【发布时间】:2012-11-28 12:15:20
【问题描述】:

我有两个具有相同标识列的数据表。我想用另一个表中的其他列值更新一个表中的一个列值。例如:

这是两张表:

表1:

       ID         Name           Amount
     ------      -------        ---------
        1          AA             0
        2          BB             0
        3          CC             0

表2:

       ID        Amount
     ------    ---------
        1        5000
        2        6000
        3        7000            

我想要的数据表应该是这样的:

所需表:

       ID         Name           Amount
     ------      -------        ---------
        1          AA             5000
        2          BB             6000
        3          CC             7000

我不想使用 for 循环。如何使用 LINQ 实现这个结果?

【问题讨论】:

  • 再次发表关于不想使用 for 循环的任意评论。它确实引出了一个问题:为什么不呢? =)
  • 您是否希望我们在不显示您尝试过的情况下为您编写它。
  • 此外,LINQ 通常用于创建新的集合/视图,而不是在现有的集合/视图中产生副作用。使用 for 或 foreach 似乎足够合理。
  • 我使用 for 循环编写了代码。这就是为什么我提到不要使用 for 循环。我想知道如何使用 LINQ?
  • 这对来说可能很明显,但对其他人来说却不是。请在您的问题中包含此类信息(以及相关示例)。 =)

标签: c# asp.net visual-studio-2010 linq


【解决方案1】:

这里将 Table1 视为“DTTable1”,将 Table2 视为 DTTable2:

DTTable1.AsEnumerable().Join(DTTable2.AsEnumerable(), 
                     dt1_Row => dt1_Row.ItemArray[0],
                     dt2_Row => dt2_Row.ItemArray[0],
                     (dt1_Row, dt2_Row) => new { dt1_Row, dt2_Row }).ToList() 
                     .ForEach(o => o.dt1_Row.SetField(2, o.dt2_Row.ItemArray[1]));

【讨论】:

  • +1,但您为不再使用 DataTable 提供了一个很好的案例。这丑了。
  • @John:谢谢。今后我会保留并遵循您的建议。
【解决方案2】:

我不喜欢我在网上看到的任何示例,所以这是我的示例

        DataTable dt = new DataTable();
        dt.Columns.Add("Year");
        dt.Columns.Add("Month");
        dt.Columns.Add("Views");
        for (int year = 2011; year < 2015; year++)
        {
            for (int month = 1; month < 13; month++)
            {
                DataRow newRow = dt.NewRow();
                newRow[0] = year;
                newRow[1] = month;
                newRow[2] = 0;
                dt.Rows.Add(newRow);
            }
        }

        dataGridView1.DataSource = dt;

        //if using Lambda 
        //var test = dt.AsEnumerable().Where(x => x.Field<string>("Year") == "2013" && x.Field<string>("Month") == "2").ToList();

        var test = (from x in dt.AsEnumerable()
                    where x.Field<string>("Year") == "2013"
                    where x.Field<string>("Month") == "2"
                    select x).ToList();

         var records = from p in dt.AsEnumerable()
                            where p.Field<string>("Year") == "2013" && p.Field<string>("Month") == "2"
                            select new
                            {
                                Views = p.Field<string>("Views")//,
                                //Month = p.Field<string>("Month")
                            };
                        foreach (var record in records)
                        {
                            //Console.WriteLine(string.Format("{0}. {1}  ({2})", record.Views, record.Month, record.Views));
                            thisCount = Convert.ToInt32(record.Views);
                            thisCount++;
                        }
        test[0][2] = thisCount.ToString();

        dt.AcceptChanges();

        //if writing to sql use  dt.SubmitChanges() instead

【讨论】:

    【解决方案3】:

    我只是在这里发布以供将来参考....

    如果您想使用 dtblToUpdateFrom 中的值更新 dtblToUpdate 但您需要加入多个列,那么这似乎可行:

    dtblToUpdate.Rows.Cast<DataRow>().Join(dtblToUpdateFrom.Rows.Cast<DataRow>(),
                r1 => new { p1 = r1["ColToJoinOn1"], p2 = r1["ColToJoinOn2"] },
                r2 => new { p1 = r2["ColToJoinOn1"], p2 = r2["ColToJoinOn2"] },
                (r1, r2) => new { r1, r2 }).ToList()
                .ForEach(o => o.r1.SetField("ColToUpdate", o.r2["ColToUpdateFrom"]));
    

    如果这有什么问题,请告诉我。

    更新:

    这里有一些测试代码表明它可以工作:

            DataTable dtblToUpdate = new DataTable();
            dtblToUpdate.Columns.AddRange(new DataColumn[]{new DataColumn("ColToJoinOn1"), new DataColumn("ColToJoinOn2"), new DataColumn("ColToUpdate")});
            dtblToUpdate.Rows.Add("1", "1", "nothing");
            dtblToUpdate.Rows.Add("2", "1", "nothing");
            dtblToUpdate.Rows.Add("3", "1", "nothing");
    
            DataTable dtblToUpdateFrom = new DataTable();
            dtblToUpdateFrom.Columns.AddRange(new DataColumn[]{new DataColumn("ColToJoinOn1"), new DataColumn("ColToJoinOn2"), new DataColumn("ColToUpdateFrom")});
            dtblToUpdateFrom.Rows.Add("1", "1", "something");
            dtblToUpdateFrom.Rows.Add("2", "1", "something");
            dtblToUpdateFrom.Rows.Add("3", "2", "something"); //Won't be updated since ColToJoinOn2 does not match in dtlbToUpdate
    
            Console.WriteLine("dtblToUpdate before update:");
            foreach(DataRow drow in dtblToUpdate.Rows)
            {
                Console.WriteLine(drow["ColToJoinOn1"].ToString() + "." + drow["ColToJoinOn2"].ToString() + " - " + drow["ColToUpdate"].ToString());
            }
    
            dtblToUpdate.Rows.Cast<DataRow>().Join(dtblToUpdateFrom.Rows.Cast<DataRow>(),
            r1 => new { p1 = r1["ColToJoinOn1"], p2 = r1["ColToJoinOn2"] },
            r2 => new { p1 = r2["ColToJoinOn1"], p2 = r2["ColToJoinOn2"] },
            (r1, r2) => new { r1, r2 }).ToList()
            .ForEach(o => o.r1.SetField("ColToUpdate", o.r2["ColToUpdateFrom"]));
    
            Console.WriteLine("dtblToUpdate after update:");
            foreach(DataRow drow in dtblToUpdate.Rows)
            {
                Console.WriteLine(drow["ColToJoinOn1"].ToString() + "." + drow["ColToJoinOn2"].ToString() + " - " + drow["ColToUpdate"].ToString());
            }
    

    输出:

    dtblToUpdate before update:
    1.1 - nothing
    2.1 - nothing
    3.1 - nothing
    dtblToUpdate after update:
    1.1 - something
    2.1 - something
    3.1 - nothing
    

    此外,当一个表缺少金额列时,请参阅此帖子以获取另一种选择。您可以在一列上连接表并获得一个新的 DataTable,其中包含两个表之间的所有唯一列:How to Left Outer Join two DataTables in c#?

    【讨论】:

    • @thevan 我知道这很旧,但我已经用一些测试代码更新了我的答案,以表明它确实更新了列。
    【解决方案4】:

    你可以使用join语句:

    from item1 in table1
    join item2 in table2 on item1.ID equals item2.ID
    select new YourType { ID = item1.ID, Name = item1.Name, Amount = item2.Amount }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多