使用反射将数据读取器转换为列表的最快方法

3

我正在使用反射将数据读取器转换为通用集合列表。 有人能建议我实现这个反射的最佳方法吗? 我想要最快的方式?


什么是“泛型集合列表”?使用 DataTable 有什么问题吗? - Keltex
应该使用Linq表达式而不是反射。相关链接:https://dev59.com/x3jZa4cB1Zd3GeqPjOC3 - nawfal
2个回答

7
我猜您想要做的是类似于以下内容:
List<MyClass> list = LoadFromDataReader<MyClass>(dataReader);

使用:

class MyClass
{
    [DataField("FirstName")] public string FirstName { get; set; }
    [DataField("LastName")] public string LastName { get; set; }
}

我通过以下方式实现:
  1. 使用 Type.GetPropertiesPropertyInfo.GetCustomAttribute 来创建一个将字段名映射到 PropertyInfo 对象的字典。
  2. 对每个记录中的每个字段调用 PropertyInfo.SetValue

可以缓存步骤(1)的结果,因为字段/属性映射不会在应用程序生命周期内更改。

如果性能是问题(即如果步骤(2)成为瓶颈),则必须避免使用反射并生成代码以直接设置属性。几种替代改进方法:

  • 使用 System.CodeDom 生成包含根据 IDataReader 上的相应字段设置属性的代码的 C# 类。请注意,System.CodeDom 在后台调用 csc.exe 编译器,因此您需要在启动时生成此代码,并在每次调用时重复使用它。
  • 使用 System.Reflection.Emit.DynamicMethod 生成设置属性的 IL 代码。比 System.CodeDom 有更少的运行时开销,但由于生成原始 IL,因此编写和调试要困难得多。作为最后一种选择使用。

1
你可以使用Lambda表达式作为反射发射的替代方案。 - davidfowl

0
这真的取决于你具体想要做什么。我实现了一个对象/接口的过程,其中我创建了保存返回数据的信息对象。然后我使用一个名为IFillable或类似的接口,将一个DR传递给对象,对象从DR中进行填充。
这样我就避免了使用反射的需要,性能也非常好。然后我还有一些通用的辅助方法,比如FillFillCollection
我得到这个想法是基于DotNetNuke框架中的CBO对象内部的东西。它也实现了一种反射方法,性能相当不错。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接