如何为通用数据库方法创建业务模型包装器?

时间:2011-03-10 14:12:05

标签: c# asp.net database-design entity-framework-4

我目前在从数据库创建POCO对象时遇到性能问题。我正在使用Entity Framework 4作为OR-Mapper。 整个应用程序现在都是原型。

我们假设我想要一些业务对象,如类'打印机'或'扫描仪'。这两个类都继承自名为Product的BaseClass。 业务类存在。

我尝试使用更通用的数据库方法。我不想为“打印机”或“扫描仪”创建表。我想要有3个表:一个名为Product,另一个名为Property和PropertyValue(将所有指定值存储到特定产品)。

在我的业务层中,我创建了一个这样的特定对象:

public Printer GetPrinter(int IDProduct)
{
  Printer item = new Printer();
  // get the product object with EF
  // get all PropertyValues
  // (with Reflection) foreach property in item.GetType().GetProperties
  // {
  //   property.SetValue("specific value")
  // }
  return item;
}

这就是EF模型的样子: enter image description here

到目前为止工作正常。现在我正在进行性能测试以检索多个集合。

我已经创建了一个原型并对其进行了多次改进以提高性能。它仍然远离可用。 我花了919ms来创建300个只包含3个属性的对象。

选择此类数据库设计的原因是具有通用数据库设计。只应在业务模型中添加新属性。

我是不是太愚蠢了,无法创建一种检索xx对象的高效方法,还是我的方法完全错了?据我了解OR-Mapper,它们基本上都是这样做的?

2 个答案:

答案 0 :(得分:5)

我认为你错过了ORM的全部观点。人们使用ORM的原因是能够持久保存商务对象并轻松检索业务对象。您正在使用ORM获取业务对象工厂的数据。工厂使用反射从ORM检索的物化类构建业务对象。这总是很慢,因为:

  • 查询编译很慢(您可以预编译)
  • 对象实现很慢(你无法避免)
  • 反思很慢(你无法避免)

IMO如果你想让这个数据库设计完全独立于你不需要ORM的业务对象的通用表,或者至少你不需要EF。

您的性能问题的原因是您的业务模型中没有遵循通用方法。所以你必须在某处将通用数据转换为特定数据=慢速操作。

如果要提高性能,请定义共享属性集并将它们放入Product中。然后使用当前的PropertyValue和Property来获取其他非共享属性,或者只使用存储键值对的ExtendedProperties表。您的实体将是具有内部类型属性,共享属性和扩展属性集合的Product类型。这是通用方法。

答案 1 :(得分:1)

首先,我不清楚你对POCO的看法。您是否手动编码这些以及您的上下文或T4生成它们?有一些很棒的文章here基准性能没有POCO,T4生成的POCO /上下文和手工编码的POCO / Context。正如预期的那样,POCO在实体框架产生的POCO路线上实现了巨大的性能节省(POCO在其基准测试中的性能提升超过15倍)。你没有说什么是DBMS ...如果MSSQL你打开了探查器并看到了什么产生了?