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

发布于 2024-10-21 09:01:29 字数 935 浏览 1 评论 0原文

我目前在从数据库创建 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 模型如下所示: 在此处输入图像描述

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

我创建了一个原型并对其进行了多次改进以提高性能。距离可用还很遥远。 我花了 919 毫秒创建了 300 个仅包含 3 个属性的对象。

选择这样的数据库设计的原因是为了具有通用的数据库设计。添加新属性只能在业务模型中完成。

我是否太愚蠢而无法创建检索 xx 对象的高性能方法,或者我的方法完全错误?据我了解OR-Mapper,他们基本上在做同样的事情?

I'm currently facing a performance problem with creating POCO objects from my database. I'm using Entity Framework 4 as OR-Mapper.
The whole application is a prototype for now.

Let's assume I want to have some business objects like classes 'Printer' or 'Scanner'. Both classes inherit from a BaseClass called Product.
The business classes exist.

I try to use a more generic database approach. I don't want to create tables for "Printer" nor "Scanner". I want to have 3 tables: One called Product, and the other Property and PropertyValue (which stores all assigned values to a specific Product).

In my business layer I do create a specific object like this:

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;
}

This is how the EF model looks like:
enter image description here

Works fine so far. For now I'm doing performance tests for retrieving multiple sets.

I've created a prototype and improved it several times to increase the performance. It is still far away from being usable.
I takes 919ms to create 300 objects who only contain 3 properties.

The reason for choosing such DB design is to have a generic database design. Adding new properties should only be done in the business model.

Am I just being too stupid to create a performant way of retrieving xx objects or is my approach totally wrong? As far as I understand OR-Mapper, they are basically doing the same?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雨的味道风的声音 2024-10-28 09:01:29

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

  • 查询编译很慢(你可以预编译它)
  • 对象物化很慢(你无法避免它)
  • 反射很慢(你无法避免它)

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

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

如果您想提高性能,请定义一组共享属性并将它们放入 Product 中。然后,可以使用当前的 PropertyValue 和 Property 作为其他非共享属性,也可以仅使用存储键值对的 ExtendedProperties 表。您的实体将属于 Product 类型,具有内部类型属性、共享属性和扩展属性的集合。这是通用方法。

I think you missed whole point of ORM. The reason why people are using ORM is to be able to persist buisness objects and easily retrieve business objects. You are using ORM to get just data for your business objects' factories. Factories are using reflection to build business object from materialized classes retrieved by ORM. This will always be very slow because:

  • Query compilation is slow (you can precompile it)
  • Object materialization is slow (you can't avoid it)
  • Reflection is slow (you can't avoid it)

IMO if you want to follwo this DB design to have generic tables absolutely independent on your business objects you don't need ORM or at least you don't need EF.

The reason for your performance problems is that generic approach is not follwed in your business model. So you must somewhere convert generic data to specific data = slow operation.

If you want to improve performance define set of shared properties and place them into Product. Then either use your current PropertyValue and Property for additional non shared properties or use simply ExtendedProperties table storing key value pairs. Your entities will be of type Product with inner type property, shared properties and collection of extended properties. That is generic approach.

北音执念 2024-10-28 09:01:29

首先,我不清楚 POCO 有什么用处。这些是您手动编写的代码,还是您的上下文或 T4 生成的? 这里有一些很棒的文章来衡量性能没有 POCO,T4 生成 POCO/上下文和手动编码 POCO/上下文。正如预期的那样,与实体框架生成的 POCO 相比,采用 POCO 路线可以节省巨大的性能(在其基准测试中性能提高了 15 倍以上)。你没有说什么 DBMS...如果 MSSQL 打开探查器并查看正在生成什么?

Firstly, it's not clear to me what you have in the way of POCOs. Did you hand code these and your context or T4 generate them? There are some great articles here that benchmark performance with no POCO, T4 Generated POCOs/Context and hand coded POCOs/Context. As expected there is HUGE performance savings going with POCOs (more than a 15-fold boost in performance in his benchmark) going the POCO route over those generated by the Entity Framework. You don't say what DBMS...if MSSQL have you turned on the profiler and see what's being generated?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文