我应该为每个使用的数据库都有一个类吗?

时间:2008-12-14 04:02:00

标签: c# database business-objects

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

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

6 个答案:

答案 0 :(得分:2)

我建议使用面向对象的解决方案。据推测,您的数据库设计有表示逻辑数据分组的表。这些表中的每一个都可能映射到系统中的一个类,尽管在某些情况下,它可能不止一个表组成一个对象,或者表可能有多个类使用子类映射到它们。如果您需要显示来自多个表的数据 - 比如包含来自与订单关联的客户的一些数据的订单列表 - 那么您可以使用视图,联接或存储过程来构造表示视图类的对象视图/ join / sp。

中的选定数据

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

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

答案 1 :(得分: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访问这些结果集。

或者您可以通过将其加入到您的某个数据库中的VIEW中来更轻松地处理和维护您的联接。

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

答案 2 :(得分:1)

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

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

当然,在每种情况下都可能不可行。它也可以与其他模式集成,如其他答案所暗示的那样。无论你选择何种方法,我都相信你会面临权衡。一切顺利!

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

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

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

答案 5 :(得分: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可以使用索引和有效执行连接的其他机制,避免从磁盘加载不需要的页面。也许您所有的个人查询都会这样做,但通常情况下,数据库可以比业务逻辑代码更高效地执行一个数量级。 (当然,如果连接跨越物理数据库边界,则可能会丢失该优势。)