如何为复杂的对象模型实现存储库模式?


21

我们的数据模型具有将近200个类别,可以分为大约十二个功能区域。使用域本来很好,但是分隔不是那么干净,我们不能更改它。

我们正在重新设计DAL以使用实体框架,而我所看到的大多数建议都建议使用存储库模式。但是,这些示例都没有真正处理复杂的对象模型。我发现一些实现建议使用每个实体存储库。对于大型,复杂的模型,这似乎是荒谬的且不可维护的。

真的有必要为每个操作创建一个UnitOfWork,并为每个实体创建一个Repository吗?我可能会参加数千堂课。我知道这是不合理的,但是我发现在复杂模型和实际业务应用程序上实现存储库,工作单元和实体框架的指导很少。

Answers:


6

首先,您将遍历拥有的每个实体并问自己​​:

单独保留该实体是否有意义?

我的意思是,在您的对象模型中,某些实体可能以主从关系包含在其他实体中。如果您的实体高度依赖于另一个实体,则不要单独为此实体创建一个存储库,因为它本身不可能持久保存。相反,您将为每个父类创建一个存储库,并确保子实体和其他关系同时保留。

我不喜欢他们在您提供的链接中如何实现UnitOfWork模式。我建议您按照这些方针做更多的事情。您不必为每个存储库定义一个类。每个存储库都可以使用相同的类,在操作的整个生命周期中,每个存储库都有自己的UnitOfWork类实例。您还可以在不同的存储库中重复使用相同的UnitOfWork来进行要同时保留的更改。


不错的链接!我正在检查。
埃里克·法尔斯肯

尽管我最终没有使用提供的模式,但是您的链接(和答案)最有帮助。我最终使用了一个包装类,该包装类代理了Add / Attach / Remove / SaveChanges方法以用作通用存储库,然后添加了一个Query / QuerySingle / QueryAll方法,该方法接受自定义查询类来保存我的查询实现。这很好,因此我可以执行LINQ和T-SQL查询,而无需直接涉及EF。
埃里克·法尔斯肯

实体框架及其事务的使用,已经是工作单元模式的实现。
格雷格·伯格哈特

1
链接已死...
Newtopian

3

也许您应该看看Domain-Driven Design。建议将您的对象分组到聚合中,并仅为每个聚合的Root实体创建存储库。这是将订单引入大型复杂对象模型的好方法。

您的不同功能区域可能是“ 绑定上下文”。如果不清楚边界之间的分离,可以使用多种技术来处理重叠的边界上下文。


0

您为“存储库模式”数据库设计找到了什么理论基础?我猜都没有。这是虚假的前提之上的一层复杂性:“持久层”是您需要与之隔离的东西。据我所知,它对关系设计原则的广泛编程无知,以及对应用程序OO设计的预设中心性的泛化。但这并不能证明其存在的合理性,更不用说理论依据了。

30年以来,数据库设计的“一条真实道路”没有改变:分析数据。查找键和约束以及多对一关系。根据Boyce-Codd范式设计表格。使用视图和存储过程来方便数据访问。

尽管SQL DBMS可能不受欢迎,但它提供了比程序员可以提供的任何东西更好的隔离层。的确,随着数据库的更改,用于访问它的SQL可能必须更改。但是请注意,无论是否存在中介层,都是如此。只要应用程序使用视图和存储过程来访问DBMS,普通的SQL工程工具就会指示对基础数据库的更改何时使这些视图和存储过程无效。

当然,挑战就在于此。中介层为程序员提供了隔离的错觉和编写代码的舒适性,他知道该怎么做。学习数据库设计和SQL需要学习一些新知识。大多数人宁愿死也不愿思考,许多人成功了。

团队中的某人无疑会反对编写SQL支持200个类的工作。毫无疑问。但这至少是有用的工作。如果您通过模仿OO设计来设计数据库,那么您还将做很多工作,很多工作都没有用,并且会破坏DBMS为您提供的大多数服务。

例如,您打算在数据库中反映工作单元(我想是一个表或多个表)。 工作单位是一个内置的DBMS的服务:begin transaction...更新数据库... commit transaction。除了将类映射到SQL中的数据库表之外,没有任何模型。

您的问题是4年前发布的。我之所以回答是因为它最近以某种方式被“更新”,表明它仍对某人有些兴趣。我希望我的回答会鼓励读者将基本关系理论应用于该问题,而不是采用无意义的解决方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.