我想对一组项目执行Except操作。
代码是这样的:
IEnumerable<DataGridViewColumn> dgvColumns = dataGridView.Columns.OfType<DataGridViewColumn>();
IEnumerable<DataColumn> dsColumns = dataSet.Tables[0].Columns.OfType<DataColumn>();
现在,如何从dataSet.Tables [0]中选择不在dgvColumns中的列? 我知道DataGridView中的Columns与DataSet中的Columns类型不同。我想只获取一部分常见值。像这样:
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>;
但我收到两个错误:
所以解决方案是构建一个类然后使用它而不是隐含的类型局部变量。但我认为仅仅因为这个原因开发一个班级是一个不必要的开销。
这个问题还有其他解决办法吗?
答案 0 :(得分: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
,因此您创建此类型的每个对象都被视为一个不同的值。试试这个*:
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);
*注意:Where
的上述表达式中的dsDgvColumns
比SkipWhile
更有意义,因为它会将指定的过滤器应用于所有结果。 SkipWhile
只会应用过滤器,只要它是真的,然后就会停止应用它。换句话说,如果DataGridViewColumn
未绑定到DataSet
的{{1}}位于DataGridView
的开头,它就会有用;但不是如果它在中间或结尾。