【发布时间】:2009-05-01 16:08:36
【问题描述】:
我正在使用反射将 datareader 转换为通用集合列表。任何人都可以 建议我为此实施反射的最佳方法?我要最快的路吗?
【问题讨论】:
-
“通用集合列表”是什么意思?使用
DataTable有什么问题? -
应该使用 linq 表达式而不是反射。相关:stackoverflow.com/questions/19841120/…
我正在使用反射将 datareader 转换为通用集合列表。任何人都可以 建议我为此实施反射的最佳方法?我要最快的路吗?
【问题讨论】:
DataTable 有什么问题?
我假设你想要做的是这样的:
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,这更难编写和调试。作为最后的选择。【讨论】:
这真的取决于你正在做什么。我实现了一个对象/接口过程,在该过程中我创建了保存返回数据的信息对象。然后我使用一个接口 IFillable 或类似的东西将 DR 传递给对象,并且对象从 DR 中进行水合。
这样我就避免了反射的需要,而且性能很棒。然后,我为Fill 和FillCollection 提供了一些通用辅助方法。
我的想法是基于 DotNetNuke 框架的 CBO 对象内部的东西。它还实现了反射方法,性能相当不错。
【讨论】: