2010-07-22 56 views
0

我想對集合項目執行Except操作。LINQ從集合A中選擇不在集合B中的項目

代碼是這樣的:

IEnumerable<DataGridViewColumn> dgvColumns = dataGridView.Columns.OfType<DataGridViewColumn>(); 
IEnumerable<DataColumn> dsColumns = dataSet.Tables[0].Columns.OfType<DataColumn>(); 

現在,如何從dataSet.Tables選擇列[0],它是不是在dgvColumns? 我知道DataGridView中的列與DataSet中的列不同。我只想拿起一些常見的值。像這樣:

 var ColumnsInDGV = from c1 in dgvColumns 
          join c2 in dsColumns on c1.DataPropertyName equals c2.ColumnName 
          select new { c1.HeaderText, c1.DataPropertyName, c2.DataType, c1.Visible }; 

上面的代碼選擇了我在兩個集合中的「列」。所以我因子評分我將創造另一套「列」是在DataSet的:

var ColumnsInDS = from c2 in dsColumns select new { HeaderText = c2.ColumnName, DataPropertyName = c2.ColumnName, c2.DataType, Visible = false }; 

,現在,我將能夠藉此在除了這樣的:

var ColumnsOnlyInDS = ColumnsInDS.Except<ColumnsInDGV>; 

但我得到兩個錯誤:

  1. 類型或命名空間名稱「ColumnsInDGV」找不到(是否缺少using指令或程序集引用?)
  2. 無法分配方法G羣到隱式類型的局部變量

所以解決方案是建立一個類,然後用它來代替隱式類型化的局部變量。但我認爲僅僅因爲這個原因纔開發一個類是一個不必要的開銷。

這個問題還有其他解決方案嗎?

回答

3

你已經差不多了。你只需要編寫:的

// use() to pass a parameter 
// type (should) be inferred 
var ColumnsOnlyInDS = ColumnsInDS.Except(ColumnsInDGV); 

代替:

// do not use <> - that passes a type parameter; 
// ColumnsInDGV is not a type 
var ColumnsOnlyInDS = ColumnsInDS.Except<ColumnsInDGV>; 

更新:那麼,上面居然不起作用,因爲Except取決於平等兩個序列進行比較的項目;顯然,您的匿名類型沒有覆蓋object.Equals,因此您創建的此類型的每個對象都被視爲不同的值。在上述表達式WheredsDgvColumns更有意義比SkipWhile,因爲它將應用指定的過濾器超過所有結果:試試這個*代替:

var dgvColumns = dataGridView.Columns.Cast<DataGridViewColumn>(); 
var dsColumns = dataSet.Tables[0].Columns; 

// This will give you an IEnumerable<DataColumn> 
var dsDgvColumns = dgvColumns 
    .Where(c => dsColumns.Contains(c.DataPropertyName)) 
    .Select(c => dsColumns[c.DataPropertyName]); 

// Then you can do this 
var columnsOnlyInDs = dsColumns.Cast<DataColumn>().Except(dsDgvColumn); 

*注。 SkipWhile將只應用過濾器,只要它是真實的,然後將停止應用它。換句話說,如果您的DataGridViewColumn未綁定到您的DataSet位於DataGridView開始;但如果它在中間或結束則不會。

+0

謝謝!第一個解決方案不起作用,沒有編譯器錯誤,但已返回所有列。第二種解決方案在執行'var dsDgvColumns = dgvColumns.Select(c => dsColumns [c.DataPropertyName])'後運行, dsDgvColumns中有一個空列。也許原因是我在DataGridView中有一列不在DataSet中。如何以dsDgvColumns不包含空值的方式修改上述查詢? – Wodzu 2010-07-23 09:51:29

+0

我已經像這樣修改它來擺脫空值。我不知道這是否是最佳方法來做到這一點? var dsDgvColumns = dgvColumns.SkipWhile(c => dsColumns [c.DataPropertyName] == null) .Select(c => dsColumns [c.DataPropertyName]); – Wodzu 2010-07-23 10:18:14

+0

@Wodzu:'哪裏比'SkipWhile'更合適。另外,我想到了爲什麼第一個解決方案不起作用。看我的編輯。 – 2010-07-23 11:43:19

相關問題