使用反射将数据读取器转换为列表的最快方法
Posted
技术标签:
【中文标题】使用反射将数据读取器转换为列表的最快方法【英文标题】:Fastest way to use reflection for converting datareader to list 【发布时间】:2009-05-01 16:08:36 【问题描述】:我正在使用反射将 datareader 转换为通用集合列表。任何人都可以 建议我为此实施反射的最佳方法?我要最快的路吗?
【问题讨论】:
“通用集合列表”是什么意思?使用DataTable
有什么问题?
应该使用 linq 表达式而不是反射。相关:***.com/questions/19841120/…
【参考方案1】:
我假设你想要做的是这样的:
List<MyClass> list = LoadFromDataReader<MyClass>(dataReader);
与:
class MyClass
[DataField("FirstName")] public string FirstName get; set;
[DataField("LastName")] public string LastName get; set;
我这样做是:
-
使用
Type.GetProperties
和PropertyInfo.GetCustomAttribute
组合一个字典,将字段名称映射到PropertyInfo
对象
在每条记录的每个字段上调用PropertyInfo.SetValue
您可以缓存第 (1) 步的结果,因为字段/属性映射在应用程序的生命周期内不会改变。
如果性能是一个问题(即如果步骤 (2) 成为瓶颈),那么您必须避免使用反射并生成代码来直接设置属性。一些替代改进:
使用System.CodeDom
生成一个C# 类,其中包含根据IDataReader
上的相应字段设置属性的代码。请注意,System.CodeDom
在后台调用 csc.exe
编译器,因此您需要在启动时生成一次此代码,并在每次调用时重复使用它。
使用System.Reflection.Emit.DynamicMethod
生成设置属性的IL 代码。比System.CodeDom
更少的运行时开销,但由于您正在生成原始IL,这更难编写和调试。作为最后的选择。
【讨论】:
您可以使用 Lambda 表达式替代反射发射。【参考方案2】:这真的取决于你正在做什么。我实现了一个对象/接口过程,在该过程中我创建了保存返回数据的信息对象。然后我使用一个接口 IFillable
或类似的东西将 DR 传递给对象,并且对象从 DR 中进行水合。
这样我就避免了反射的需要,而且性能很棒。然后,我为Fill
和FillCollection
提供了一些通用辅助方法。
我的想法是基于 DotNetNuke 框架的 CBO 对象内部的东西。它还实现了反射方法,性能相当不错。
【讨论】:
以上是关于使用反射将数据读取器转换为列表的最快方法的主要内容,如果未能解决你的问题,请参考以下文章
将列表写入 pandas 数据帧到 csv,从 csv 读取数据帧并再次转换为列表而无需字符串