LINQ从集合A中选择不在集合B中的项目

发布于 2024-09-11 14:50:31 字数 1212 浏览 9 评论 0原文

我想对一组项目执行 except 操作。

代码是这样的:

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 };

现在我将能够执行 except 这样的操作:

var ColumnsOnlyInDS = ColumnsInDS.Except<ColumnsInDGV>;

但我收到两个错误:

  1. 无法找到类型或命名空间名称“ColumnsInDGV”(您是否缺少 using 指令或程序集引用?)
  2. 无法将方法组分配给隐式类型的局部变量

因此解决方案是构建一个类,然后使用它而不是隐式类型的局部变量。但我认为仅仅为了这个原因开发一个类是不必要的开销。

对于这个问题还有其他解决方案吗?

I would like to perform an Except operation on set of items.

Code is like this:

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

Now, how to select Columns from dataSet.Tables[0] which are not in dgvColumns?
I know that Columns from DataGridView are different type than Columns in DataSet. I want to pick up only a subset of common values. Like this:

        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 };

Above code selects me "columns" that are in both sets. So I tought I will create another set of "columns" that are in DataSet:

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

and now that I will be able to perfrom Except like this:

var ColumnsOnlyInDS = ColumnsInDS.Except<ColumnsInDGV>;

But I am getting two errors:

  1. The type or namespace name 'ColumnsInDGV' could not be found (are you missing a using directive or an assembly reference?)
  2. Cannot assign method group to an implicitly-typed local variable

So the solution would be to build a class and then use it instead of implictly - typed local variable. But I think that developing a class only for this reason is a not necessery overhead.

Is there any other solution for this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ゞ花落谁相伴 2024-09-18 14:50:31

你差不多已经明白了。你只需要写:

// 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);

*注意:上面的 dsDgvColumns 表达式中的 WhereSkipWhile 更有意义,因为它将在 dsDgvColumns 上应用指定的过滤器em>所有结果。 SkipWhile 只会在过滤器为 true 时应用过滤器,然后停止应用它。换句话说,如果您的 DataGridViewColumn 未绑定到 DataSet 且位于 DataGridView开头,那么它就会起作用;但如果是在中间或最后则不然。

You've almost got it. You just need to write:

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

instead of:

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

Update: So, the above actually doesn't work because Except depends on comparing items in two sequences for equality; obviously, your anonymous type has not overriden object.Equals and so each object that you create of this type is treated as a distinct value. Try this* instead:

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);

*Note: Where in the above expression for dsDgvColumns makes more sense than SkipWhile because it will apply the specified filter over all results. SkipWhile would only apply the filter as long as it was true and would then stop applying it. In other words it would work if your DataGridViewColumn not bound to your DataSet were at the beginning of the DataGridView; but not if it were in the middle or at the end.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文