4

首先,让我解释一下我在做什么。我需要一个订单,它被分成不同的数据库,并打印出这个非常大的订单。我从订单中需要的是来自不同数据库的大约 100 列左右。我正在做的方式是使用连接查询并将所有列值分配给我的一个大型 Order 类中的一个变量。这已经开始变得麻烦了。我想知道不是有一个由 100 名左右的成员组成的班级来组成订单。我应该为我使用的每个数据库设置一个类,然后使用它吗?

让我补充一下。基本上,将对象映射到原始数据库表还是结果集更好。因为我将对象映射到结果集而不是单个表。

4

6 回答 6

2

我会推荐一个面向对象的解决方案。大概您的数据库设计有表示数据逻辑分组的表。这些表中的每一个都可能映射到系统中的一个类,尽管在某些情况下,它可能由多个表组成一个对象,或者一个表可能使用子类映射到多个类。如果您需要显示来自多个表的数据——比如说一个订单列表以及与订单相关的客户的一些数据——那么你可以使用视图、连接或存储过程来构造一个视图类的对象,该对象表示view/join/sp 中选择的数据。

本质上,我所描述的是一个 N 层数据架构,其中您有一个低级数据访问层,用于处理来自 SQL 方向的数据——表、视图、存储过程。在此之上可能是处理通用数据对象并与数据访问层接口以从数据库存储/检索对象的通用对象层。最后,在此之上,您有一个强类型的业务对象层,您的应用程序使用语义链接到您的应用程序的类——订单、客户、发票等。实现这种类型的通用架构有许多不同的模式,您应该调查几个,看看哪个最适合您的应用程序需要。

就个人而言,我认为构建应用程序以处理域上下文中的对象,而不是简单地作为表数据,将改进您的代码。它应该提高可理解性和可维护性。您将能够将行为封装在您的域类中,而不是将其传播到整个应用程序中。当然,这假设您遵循良好的设计实践,但使用 OO 设计会鼓励这一点。从显示逻辑中分离出业务和数据逻辑也将使您的应用程序更加可测试,将单体类分解为更小、更集中且相互关联的类。

于 2008-12-14T04:58:49.087 回答
1

为什么不单独从单个数据库中加载数据?

例如,您的 Order 对象的构造函数如下所示:

Method New Order(orderId) {
   Get Database 1 Details
   Load Details into appropriate Variables
   Get Database 2 Details 
   Load Details into appropriate Variables
   Get Database **N** Details 
   Load Details into appropriate Variables
}

它使维护涉及单个数据库的 sql 变得更容易,并且每个数据库都不会有十几个不同的类。

另一种选择是有一个存储过程,它返回多个结果集,您可以通过代码中的 DataSet 访问这些结果集。

或者,您可以通过将其转换为您的一个数据库中的视图来使您的连接更易于处理和维护。

您真正需要考虑的一件事是维护。六个月不阅读代码对你来说是多么容易维护,甚至对于其他一些开发人员来说,在没有先验知识的情况下维护代码是多么容易。选择您认为最容易维护的范例,然后以这种方式编码

于 2008-12-14T04:31:20.017 回答
1

解决此问题的一种优雅而简单的方法是 Active Record 模式:

http://en.wikipedia.org/wiki/Active_record_pattern

当然,它可能并非在所有情况下都可行。正如其他答案所暗示的那样,它也可以与其他模式集成。我相信无论您选择哪种方法,您都将面临权衡取舍。祝一切顺利!

于 2008-12-14T07:49:05.903 回答
0

这听起来就像你对我的偏好。您希望如何使用它?将其作为单独的 C# 对象使用会更容易,还是将其作为多个 SQL 表使用会更容易?

于 2008-12-14T04:10:30.527 回答
0

我会考虑创建一个类来处理每个单独的数据存储中的数据。

然后,我会考虑使用一种模式,比如 Facade 将这些子系统组合在一起。在网络上搜索“设计模式”和“外观”以获取更多信息。然后,外观可以解释单独数据存储中的数据之间的任何特定交互。

对我来说,维护逻辑分组的代码要容易得多,并且为单独的数据存储设置单独的类对我来说很有意义。

于 2008-12-14T06:44:01.260 回答
0

我在这里违背了原则,但我会说保持这个对象映射到结果集,并将连接保持在数据库中,可能是一个更好的主意。

对于业务逻辑,“订单”通常是一个单一的有凝聚力的概念(至少,这就是您开始构建它的方式)。它被映射到多个表(或数据库)这一事实是否可能是数据捕获方式的产物?在分解之前,我会问自己这些问题:

  • 用其他对象组合顺序是否有实实在在的好处?
  • 属性是否有不同的基数?即一些是按订单的,而另一些是按行项目的?
  • 您可以为组合对象重用现有代码吗?
  • 您是否启用了更容易与多个对象进行的其他交互?

如果您对这些问题中的任何一个都没有回答是,我敢打赌,如果您的代码仅将订单作为原子对象处理,并且让数据库隐藏它来自何处的复杂性(你甚至可以为此使用视图)。

绝对数量的属性通常不是分解接口的理由。但是,如果订单对象本身的复杂性(或大小)让您失望,您可能会尝试在内部简化它以使用某种通用访问器方法,例如:

private object GetOrderAttribute(string attributeName){
    // use a data structure (like a hash table) to store and access internally
}
...
output("Quantity: " + GetOrderAttribute("quantity"));
// etc.

另一个注意事项:虽然在逻辑系统设计中性能很少是您首先关注的问题,但如果数据库执行连接,大多数涉及数据库表连接的情况会执行得更好,因为 DBMS 可以使用索引和其他机制来有效地执行连接并避免加载磁盘中不需要的页面。也许你所有的个人查询也这样做,但通常这是数据库可以比业务逻辑代码更有效地执行一个数量级的事情。(当然,如果连接跨越物理数据库边界,则可能会失去这种好处。)

于 2008-12-14T17:39:46.850 回答