2012-06-27 76 views
3

我有2個數據表,一個是查找列表,另一個是數據。我在包含數據的表中有許多列列,其中一列是查找數據表的外鍵列。LINQ和NOT IN子句

我想爲所有查找行生成另一個列表,它不會出現在保存基於外鍵列上的Id的數據的表中。

我想使用LINQ查詢,或一些在2個數據表

作品,如果我在做一個SQL NOT IN。

乾杯

以下是一些數據。我希望新的列表中有4類和5類。

  DataTable dtData = new DataTable("Data"); 
     dtData.Columns.Add("Id", Type.GetType("System.Int32")); 
     dtData.Columns.Add("CategoryId", Type.GetType("System.Int32")); 
     dtData.Columns.Add("Qty", Type.GetType("System.Int32")); 
     dtData.Columns.Add("Cost", Type.GetType("System.Decimal")); 
     dtData.Columns.Add("TotalCost", Type.GetType("System.Decimal")); 
     dtData.Columns.Add("TypeId", Type.GetType("System.Int32")); 

     dtData.Rows.Clear(); 

     DataRow row = dtData.NewRow(); 
     row["Id"] = 1; 
     row["CategoryId"] = 1; 
     row["Qty"] = 3; 
     row["Cost"] = 237.00; 
     row["TotalCost"] = 711.00; 
     row["TypeId"] = DBNull.Value; 
     dtData.Rows.Add(row); 

     row = dtData.NewRow(); 
     row["Id"] = 2; 
     row["CategoryId"] = 1; 
     row["Qty"] = 5; 
     row["Cost"] = 45.00; 
     row["TotalCost"] = 225.00; 
     row["TypeId"] = DBNull.Value; 
     dtData.Rows.Add(row); 

     row = dtData.NewRow(); 
     row["Id"] = 3; 
     row["CategoryId"] = 3; 
     row["Qty"] = 30; 
     row["Cost"] = 1.00; 
     row["TotalCost"] = 30.00; 
     row["TypeId"] = 1; 
     dtData.Rows.Add(row); 

     row = dtData.NewRow(); 
     row["Id"] = 4; 
     row["CategoryId"] = 2; 
     row["Qty"] = 1; 
     row["Cost"] = 15.00; 
     row["TotalCost"] = 15.00; 
     row["TypeId"] = 2; 
     dtData.Rows.Add(row); 

     row = dtData.NewRow(); 
     row["Id"] = 5; 
     row["CategoryId"] = 1; 
     row["Qty"] = 4; 
     row["Cost"] = 3.00; 
     row["TotalCost"] = 12.00; 
     row["TypeId"] = 2; 
     dtData.Rows.Add(row); 

     DataTable dtlookup = new DataTable("LookUp"); 
     dtlookup.Columns.Add("CategoryId", Type.GetType("System.Int32")); 
     dtlookup.Columns.Add("Description", Type.GetType("System.String")); 

     dtlookup.Rows.Clear(); 

     DataRow lup = dtlookup.NewRow(); 
     lup["CategoryId"] = 1; 
     lup["Description"] = "Category 1"; 
     dtlookup.Rows.Add(lup); 

     lup = dtlookup.NewRow(); 
     lup["CategoryId"] = 2; 
     lup["Description"] = "Category 2"; 
     dtlookup.Rows.Add(lup); 

     lup = dtlookup.NewRow(); 
     lup["CategoryId"] = 3; 
     lup["Description"] = "Category 3"; 
     dtlookup.Rows.Add(lup); 

     lup = dtlookup.NewRow(); 
     lup["CategoryId"] = 4; 
     lup["Description"] = "Category 4"; 
     dtlookup.Rows.Add(lup); 

     lup = dtlookup.NewRow(); 
     lup["CategoryId"] = 5; 
     lup["Description"] = "Category 5"; 
     dtlookup.Rows.Add(lup); 


var qqq = (from r in dtlookup.AsEnumerable() 
        where !dtData.AsEnumerable().Any(b => b["CategoryId"] == r["CategoryId"]) 
        select r).ToList(); 
+0

無關反饋...'Type.GetType(「 System.Int32「)'...這將是'typeof(int)',這更簡單。同樣,'typeof(decimal)' –

+3

看起來像http://stackoverflow.com/questions/1164770/linq-not-in-select-on-datatable dublicate你見過那個嗎? – Heki

+1

難道你至少不能用容易消費的形式展示你的樣本數據嗎?我的意思是,我可以瞭解數據是什麼......在想到它之後...... –

回答

2

我懷疑這是dahlbyk的答案,幫助你,所以我會粘貼在這裏。

Linq not in select on datatable


,如果你使用它的國家的序列除了將工作:使用System.Linq的

; ...

var ccList = from c in ds.Tables[2].AsEnumerable() 
      select c.Field<string>("Country"); 
var bannedCCList = from c in ds.Tables[1].AsEnumerable() 
        select c.Field<string>("Country"); 
var exceptBanned = ccList.Except(bannedCCList); 

如果你需要一個國家不禁止整行,你可以嘗試一個左外連接:

var ccList = ds.Tables[2].AsEnumerable(); 
var bannedCCList = ds.Tables[1].AsEnumerable(); 
var exceptBanned = from c in ccList 
        join b in bannedCCList 
        on c.Field<string>("Country") equals b.Field<string>("Country") into j 
        from x in j.DefaultIfEmpty() 
        where x == null 
        select c; 
+0

請「嘿嘿」我需要VB.Net中的第二個代碼,我有轉換與「converter.telerik」。com /「,附加感謝 –

+0

@BeldiAnouar不幸的是,我對VB沒有任何經驗,但看起來你只需要在這裏和那裏添加一個空格,即'Into jFrom' - >'Into j From'和'x Is Nothingc' - >'x Is Nothing c'或者(對我來說,這會更有意義)'x沒有選擇c'。 – Heki

0

您可以使用DataTable.AsEnumerable()擴展方法返回數據的可枚舉集合。從那裏你可以使用LINQ來有效地查詢你的數據。

var myData = myDataTable.AsEnumerable() 

編輯:如果您需要確定一個ID被包含在你的數據表,你必須先選擇出的ID列表(因爲你不能比較整個DataRow對象)。

bool idExists = dtData 
        .AsEnumerable() 
        .Select(item => (int) item["Id"]) 
        .Contains(myId); 
+0

我試過這個var qqq =(從dtlookup.AsEnumerable()中的r) where!dtData.AsEnumerable()。Any(b => b [「CategoryId」] == r [「CategoryId」]) select r)。 ToList(); – trailerman