我正在将二进制文件读入(t)的绑定列表中;绑定到datagridview .
文件中的每一行代表一个事务,但我需要合并和/或过滤符合特定条件的事务 .
我从机械的角度知道如何做到这一点(在添加每个项目时循环列表,添加新项目,或者将数据与现有项目合并),但我正在寻找练习,模式,现有组件或我缺少的其他东西(我正在为搜索关键字画一个空白) .
如果我没有,我不想重新发明轮子 . 我特别关注速度和性能问题,在某些情况下要处理100k以上的记录 .
目前正在使用.NET 2.0,但如果存在特别性感的解决方案,则将移至3.5 .
Update 我've changed the solution to 3.5 so that'不再是问题 . 我应该指出这个项目是VB.NET,但是我可以为这个特定的函数添加一个新的C#库来利用C#迭代器 .
2 回答
是的,你想要3.5因为这给你LINQ语言集成查询 .
性能成本很低,但对于大型记录集,您可以通过使用PLINQ(并行处理)来抵消这一点 .
LINQ是处理集合的声明性,功能性方法 .
您需要的概念:
() =>
从一组10,000个字符串中考虑,您希望前100个长度超过24个字符:
从一组
Person
对象中,您想要返回名称,但它们分为firstName
和lastName
属性 .这将返回
IEnumerable<string>
.从同一组你想要的平均年龄:
最年轻的10人:
每个人,按姓氏的第一个字母分组:
返回
IGrouping<char, Person>
姓氏以S开头的最老的25个人的姓名:
想象一下,你需要在
foreach
循环中编写多少代码才能实现这一目标,以及在代码中引入缺陷或错过优化的空间有多大 . LINQ语法的声明性质使其更易于阅读和维护 .有一种替代语法是SQL-ish,但显示了如何真正定义针对任意对象集的查询 . 考虑一下你想得到名字叫“Bob”的人:
它看起来很奇怪,但如果你从2.0跳起来,这是有效的C#代码 .
我唯一的警告是,一旦你使用LINQ,你可能会拒绝再次使用2.0 .
有很多很好的资源可用于学习LINQ语法 - 它不需要很长时间 .
更新
针对第1条评论的其他注意事项:
您已经拥有了一个非常强大的工具,可以使用C#2.0 - 迭代器 .
考虑:
那么,这有什么值得注意的呢?
GetRecords()
方法是一个迭代器块,yield
关键字按请求返回结果("lazy evaluation") .这意味着当你调用
DisplayRecords()
时,它会调用GetRecords()
,但只要GetRecords()
有一个Record
,它就会将它返回到DisplayRecords()
,然后可以用它做一些有用的事情 . 当foreach
块再次循环时,执行将返回GetRecords()
,这将返回下一个项目,依此类推 .这样,您就不必等待从磁盘读取100,000条记录,然后才能开始排序和显示结果 .
这给了一些有趣的可能性;是否可以在您的情况下使用它取决于您(例如,您不希望刷新网格绑定100,000次) .
听起来你想在伪LINQ中做这样的事情:
data.GroupBy().Select(Count()).Where()
- 按一些标准分组(合并),计算每组中的数字,然后按结果过滤 .但是,您建议您可能有太多数据一次性加载到内存中,因此您希望在加载数据时进行整合 . 这可以使用您自己的
GroupByCount
运算符完成,有点像这个过度简化的版本:那么你只需要
data.GroupByCount().Where()
并且你的数据在加载时都会被合并,因为foreach
只会在处理完前一个项目后加载下一个项目 .