我们有一个商业模式和相关的存储库。这由来自数据库中不同表的不同数据填充。在某些时候,在用户对数据进行更改之后,我们必须将这些更改反映回数据库。目前,这是通过将密钥与对象相关联来完成的,如下所示:
class DataObject
{
string SomeProperty;
// more properties
int Table1Id;
int Table2Id;
int Table3Id;
}
我建议通过添加标识源表的属性进行轻微清理,然后使用单个" ExternalId"属性;但是我想知道是否有更好的模式可以更好地解耦数据和业务层。
我们正在使用C#,但这是一个与语言无关的问题。
答案 0 :(得分:0)
假设您已经将对象模型映射到数据库模型,现在必须实际执行映射,并且您大致有两种选择: Active Record 或 数据映射器 。
有效记录
在选择持久性策略时,您需要做出的第一个决定是将执行映射的责任放在何处。您有两个非常不同的选项:您可以让每个实体类本身负责映射,也可以使用完全独立的类来映射到数据库。
第一个选项称为Active Record模式:在数据库表或视图中包装行的对象,封装数据库访问,并在该数据上添加域逻辑。 Active Record方法将持久性方法直接放在实体对象上。在这种情况下,Address类可能包含Save,Update和Delete等方法,以及查询数据库中Address对象的静态Load方法。
Active Record模式的典型用法是在数据库表中围绕单行创建一个强类型类包装器。因此,Active Record类通常是数据库结构的精确镜像(这将在不同工具之间变化)。许多Active Record实现将直接从数据库结构生成实体对象。
数据映射器
很好,因为Active Record模式可能很好,因此拥有一个与数据库模型不同的对象结构通常很有价值。您可能希望将多个类映射到同一个数据库表。您可能有一个遗留数据库模式,它不符合您希望在某些业务逻辑中表达的对象的形状(在我的最后几个项目中常见的情况)。
这就是我选择Data Mapper模式的地方:一层映射器对象,它在对象和数据库之间移动数据,同时保持它们彼此独立以及映射器类本身。 Data Mapper模式剥离了实体对象的大部分持久性责任,有利于实体外部的类。使用Data Mapper模式,您可以使用某种存储库访问,查询和保存实体对象。
您如何在两者之间做出选择?
杰里米·米勒在文章中说:“我个人对数据映射器解决方案的偏见非常强烈。除此之外,Active Record最适合具有更简单的域逻辑,CRUD密集型应用程序(创建,读取,更新和删除)的系统,以及域模型不需要与数据库结构有太大分歧。对于许多.NET开发团队来说,Active Record可能更舒适,因为它意味着数据中心的工作方式对于.NET团队来说更为常见,坦率地说,支持得更好通过.NET本身。我将.NET空间中的大多数持久性工具描述为Active Record工具。
另一方面,Data Mapper更适用于具有复杂域逻辑的系统,其中域模型的形状将与数据库模型显着不同。 Data Mapper还将域模型类与持久性存储区分开。对于需要使用不同数据库引擎,模式甚至不同存储机制重用域模型的情况,这可能很重要。 “
注意:大多数这些模式都来自Martin Fowler的书“企业应用程序架构模式”。如果您与编写企业应用程序有任何关系,我强烈建议您阅读本书。
有关更多信息,请查看Jeremy Miller的article。