2012-11-28 153 views
1

我有兩個具有相同標識列的數據表。我想用另一個表中的其他列值更新一個表中的一個列值。例如:更新數據表使用LINQ

這是兩個表:

表1:

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

表2:

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

我想要的數據表應該是這樣的:

DesiredTable:

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

我不想用for循環。如何使用LINQ來實現這個結果?

+1

再次這個關於不想使用for循環的任意評論。它乞求的問題:爲什麼不呢? =) –

+3

你是否希望我們爲你寫而不顯示你的嘗試。 –

+1

另外,LINQ通常用於創建新的集合/視圖,而不會在現有的集合/視圖中產生副作用。對於或者說foreach似乎足夠合理的使用。 –

回答

2

這裏考慮表1爲 'DTTable1' 和表2爲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])); 
+0

+1,但是您將成爲不再使用DataTable的絕佳案例。這太醜了。 –

+0

@John:謝謝。我將保留並遵循您的建議。 – thevan

-1

您可以使用連接語句:

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 } 
+0

-1:我在這裏沒有看到更新。 –

0

我只是張貼這在這裏以供將來參考....

如果要使用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#?

+0

嗨,這條語句不會更新列。 – thevan

+0

@thevan我知道這是舊的,但我用一些測試代碼更新了我的答案,以表明它更新列。 – Soenhay

0

我不喜歡任何的我在網絡上看到的例子,所以這裏是我的榜樣

 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