LINQ如果不在数据表中,则从集合中删除项目

时间:2011-02-21 07:41:19

标签: linq datatable

我有一个集合,其中每个项目都有一个属性“ID”。有一个数据表有一个“ID”列。

如果集合中有任何不在数据表中的值,则需要将其删除。

可以使用LINQ完成,还是需要迭代集合?

4 个答案:

答案 0 :(得分:2)

如果你想要一个DataRow的集合:

dataTable.Rows.Cast<DataTable>
      .Where(dr => myCollection.Find(s => s.ID.Equals(dr["ID"])) != null)

否则,如果您需要过滤对象的集合:

   var ids =  dataTable.Rows.Cast<DataTable>.Select(dr => Convert.ToInt32(dr["ID"]));
   var filteredCollection = myCollection.Where(s => ids.Contains(s.Id));

如果添加对System.Data.DataSetExtensions的引用,则可以缩短它:

   var ids = dataTable.AsEnumerable().Select(dr => dr.Field<int>("ID"));
   var filteredCollection = myCollection.Where(s => ids.Contains(s.Id));

答案 1 :(得分:1)

LINQ本身就是执行查询,而不是更改集合。

两个选项:

  • 仅使用原始集合中的相应值,使用LINQ创建新集合。用这个替换原始集合。 (如果对原始集合有多个引用,则不容易。)
  • 使用LINQ创建要从原始集合中删除的值集合,然后遍历该单独集合,从原始集合中删除元素。请注意,您应该实现此“要删除的值集合”(例如,通过调用ToList),否则当您从中删除项目时,您仍将在原始集合上进行迭代,这将导致异常。

我不知道数据表在索引方面做了什么,但是如果表很大,你可能想要创建一个ID的HashSet,例如。

var query = dataTable.AsEnumerable()
                     .Field<string>("ID"); 
HashSet<string> dataTableIds = new HashSet<string>(query);

这样你就可以非常便宜地检查遏制措施。

答案 2 :(得分:1)

这是一个例子,但我没有测试它

var items = new List<Item>();
var dataTable = new DataTable { Columns = { new DataColumn("ID", typeof(int)) } };
var rows = dataTable.AsEnumerable();
var itemsToRemove = items.Join(rows, item => item.ID, row => row.Field<int>("ID"), (item, row) => item);
foreach (var item in itemsToRemove)
{
    items.Remove(item);
}

我希望它对你有所帮助。它基于基于id加入两者。

答案 3 :(得分:0)

您不希望这样做,因为由于LINQ数据上下文中的更改跟踪机制,无法保证集合中包含的信息仍将在查询请求之间的数据库中。

迭代整个集合将浪费时间......重新执行查询以重新填充集合会更好。

var query = dc.Collection.Where(c => (dc.DataTable.Select(dt => dt.Customer_ID)).Contains(c.Customer_ID));