2010-01-05 44 views
4

我有一個List<string>,我有一個DataTable。比較DataRow收集到列表<T>

DataRow中的一列是ID。該列表保存此ID的實例。

DataTable被填充到定時器上。

我想返回不在DataTable中的列表中的項目到另一個列表中。

回答

12

你會想要做這樣的事情

var tableIds = table.Rows.Cast<DataRow>().Select(row => row["ID"].ToString()); 

var listIds = new List<string> {"1", "2", "3"}; 

return listIds.Except(tableIds).ToList(); 

您可以在數據表中投行是一個IEnumerable集合,然後選擇從他們每個人的「ID」列的值。然後,您可以使用Enumerable.Except擴展方法來獲取List中所有不在剛剛創建的集合中的值。

如果您需要獲取表中的值而不是列表中的值,只需反轉listIds和tableIds即可。

+0

+1的數據行的鑄造。 – mehul9595 2011-07-05 11:50:32

+0

+1。Cast是我所有那些美妙的擴展方法的缺失鏈接。 – Alain 2012-01-23 14:54:54

1

如果你的表是類似的東西:

DataTable dt = new DataTable(); 
dt.Columns.Add("ID"); 
DataRow dr = dt.NewRow(); 
dt.PrimaryKey = new DataColumn[] {dt.Columns[0]}; 
dr["ID"] = "1"; 
dt.Rows.Add(dr); 
dr = dt.NewRow(); 
dr["ID"] = "2"; 
dt.Rows.Add(dr); 
dr = dt.NewRow(); 
dr["ID"] = "3"; 
dt.Rows.Add(dr); 

和名單是這樣的:

List<string> ls = new List<string>{"1","2","4"}; 

,我們可以在列表中,而不是在數據表這種方式獲得發現的物品:

var v = from r in ls 
       where !dt.Rows.Contains(r) 
       select r; 
     v.ToList(); 
1

以合理的效率通過HashSet<T>(並注意到使得f astest方式獲得的數據進行的DataRow是通過DataColumn索引):

 HashSet<int> ids = new HashSet<int>(); 
     DataColumn col = table.Columns["ID"]; 
     foreach (DataRow row in table.Rows) 
     { 
      ids.Add((int)row[col]); 
     } 
     var missing = list.Where(item => !ids.Contains(item.ID)).ToList(); 
+0

我沒有測試過兩種方法,但你會說你的答案比bdowden更有效嗎? – Jon 2010-01-05 13:02:27

+0

除非你有大量的數據,否則不會有太多的內容,但**很少**。字符串索引器查找每一行的列。在大多數情況下,堅持使用最簡單,最容易理解的方法(只在需要時進一步優化)。 – 2010-01-05 13:29:43

+0

哦,並且在Cast/Select中有更多的枚舉器(=更多的開銷),但是同樣的:這通常不會*會產生顯着的差異。 – 2010-01-05 13:30:41