在C#/ .NET 4.0中填充和使用动态类

时间:2010-04-23 16:04:04

标签: c# collections dynamic datatable reflection.emit

在我们的应用程序中,我们正在考虑使用动态生成的类来保存大量数据。这样做的原因是我们的客户拥有不同结构的表。因此,您可以拥有一个名为“DOG”的客户表(只是这样做),其中包含“DOGID”,“DOGNAME”,“DOGTYPE”等列。客户#2可以使用相同的表“DOG”和列“ DOGID“,”DOG_FIRST_NAME“,”DOG_LAST_NAME“,”DOG_BREED“等。我们无法在编译时为这些类创建类,因为客户可以随时更改表模式。

目前我的代码可以在运行时使用反射生成“DOG”类。我想弄清楚的是如何在没有极端性能损失的情况下从DataTable(或其他一些.NET机制)填充此类。我们有一个包含~20列和~50k行的表。对所有行和列进行foreach以创建集合需要大约1分钟,这有点太长了。

我是否想要提出一个过于复杂的解决方案,或者我是否在正确的轨道上?还有其他人遇到过这样的问题吗?创建动态类是Microsoft提出的开发人员提出的解决方案。如果我们可以填充这个集合并有效地使用它,我认为它可以工作。

3 个答案:

答案 0 :(得分:3)

您尝试做的事情将在.NET 3.5中变得相当复杂。你可能最好用Dictionary<>创建一个类型。模型中数据的键/值对。

如果您可以使用.NET 4.0,则可以查看using dynamic and ExpandoObjectdynamic关键字可让您创建对真正动态对象的引用 - ExpandoObject可让您轻松添加属性和方法。所有这些都没有复杂的反射或代码逻辑。动态类型的好处是DLR执行运行时绑定信息的一些复杂缓存,以允许类型比常规反射允许更高性能。

如果您需要做的只是将数据加载到现有类型,那么您应该考虑使用EntityFrameworkNHibernate之类的内容来为您的类型提供ORM行为。

为了处理数据加载性能,我建议您考虑完全绕过DataTable并将记录直接加载到您生成的类型中。我怀疑大多数性能问题都是从原始驻留的DataTable中读取和转换值。

答案 1 :(得分:1)

您应该使用分析器来确定,究竟需要花费多少时间,然后对其进行优化。如果在设置数据时使用反射,则速度很慢。通过缓存反射的类型数据可以节省很多。

我很好奇,如果在编译时不知道成员,你将如何使用这些类?对于这种情况,您可能只需要一个简单的DataTable就可以了?

答案 2 :(得分:1)

查看PicoPoco和Massive。这些是微ORMS。 (轻量级开源ORM框架),只需将单个代码文件复制到项目中即可使用。

Massive使用ExpandoObject并进行从IDataRecord到ExpandoObject的转换,我认为这正是你想要的。

PicoPoco采用现有的普通类,并动态高效地生成一个方法(然后按顺序缓存)从数据库加载它。