我有一个约有1/2万条记录的绑定数据网格视图,可以按任何列排序。在GUI中,用户可以选择任意数量的行(有时所有行都使用CTRL + A)。从另一个来源,我得到一个大的记录ID列表(最多1000个),并需要找出哪些ID对应于选定的行。我尝试了很多方法,其中没有一种方法表现得足够快。例如:
循环选定的行集合并在ID列表中查找匹配是不可能的,因为SelectedRows计数可以是大约1/2百万的数量。
我还尝试循环访问ID列表(通常大约为1000),并为每个ID执行BindingSource.Find(“Id”,Value),它为每个ID提供行索引,然后我可以检查是否选中了行。如果网格按ID排序,这可以正常工作,但如果不是,则Find()的性能太差,无法调用1000次。
简而言之,在需要行对象ID的情况下,我需要一种快速的方法来查找最多1000行的Row.Selected状态。似乎DataGridView或DataBinding应该能够处理这个问题,但它并不明显。提前谢谢!
答案 0 :(得分:1)
我会尝试以下方法:
这是一个非常相似的例子(尽管我怀疑它的表现会非常好):
private ICollectionView _CarListView { get; set; }
private ObservableCollection<Car> _CarList;
public ObservableCollection CarList
{
get
{
if (_CarList == null)
{
//Code to build the list
//For the car filtering
this._CarListView = CollectionViewSource.GetDefaultView(_CarList);
this._CarListView.Filter = CarFilter;
}
return _CarList;
}
}
private bool CarFilter(object item)
{
Car car = item as Car;
if(car.Name.Contains(FilterText))
{
return true;
}
else
{
return false;
}
}
在您的情况下,我只是调整CarFilter(实际上是Predicate<T>
),以便您可以查找绑定到DataGridViewRow中Selected属性的属性。例如,您可以在ObservableCollection中包含的对象类型上创建一个IsSelected布尔值,并返回该项为true的位置。获得筛选后的列表结果后,请运行您提到的较小的ID列表(大约1000个元素),并查看ID匹配的位置。我会尝试对两个集合使用LINQ查询来执行该操作,该操作应该尽可能快。
如果所有其他方法都失败了,您可以回到原来的循环技术并尝试使用并行库来执行Parallel.ForEach,它将利用您的多核CPU更快地执行操作。虽然,我不会蛮力。看起来您必须进行一次传递以累积大型集合中的所选项目,然后在较小的集合中查找每个所选项目。