存储库模式和聚合根模式和实体框架

Posted

技术标签:

【中文标题】存储库模式和聚合根模式和实体框架【英文标题】:Repository Pattern and aggregate root pattern and Entity Framework 【发布时间】:2013-02-10 16:06:27 【问题描述】:

我正在根据存储库模式、聚合根和工作单元来构建我的应用程序。我正在使用 Entity Framework5 作为 ORM。

我不知道如何继续添加新实体,这些实体是聚合根并且与非聚合根的实体具有外键关系。

我不确定我之前的陈述是否有意义,但让我在这里举个例子。

Db 中的人员表(这是我的应用程序中的聚合根)

    姓名 地址线1 国家 ID

国家表(这不是聚合根,因为我可能永远不需要独立查询它们)

    国家 ID 国家/地区名称

在我的应用程序中,我有 PersonsRepository,它实现了一个通用存储库,其中 T 是聚合根。

现在,当我在我的代码中创建一个新人时,我需要将 Country 添加到 Person 对象的导航属性。如果我创建一个新的 Country 对象并将其分配给 Person 的 Country 属性并尝试保存 Person 对象,则 EF 会引发错误。我无法查询国家表,因为它不是我的聚合根。

嗯,这不是我的实际情况,但这是我想要克服的。我应该如何从这里开始?

我想到的一个想法是创建一个通用的只读存储库,用于查询数据库而不是修改它,这是继续的好方法还是我做错了什么。

提前感谢您的回复和阅读长文。

【问题讨论】:

EF 抛出了什么错误? 它抛出“无法将 Person 对象转换为类型 Country”,我认为这是完全有效的,当它是 db 中的外键时,为什么要创建一个新的 Country 对象。如果我使用数据上下文获取 Country 并在创建它时将其分配给 Person 对象的 Country 属性,它工作得很好。 【参考方案1】:

聚合根不仅仅是您可能不需要直接查询的东西。根据您的推理,您必须多次创建同一个国家/地区,因为您无法查询该国家/地区是否存在(即该国家/地区是一个需要 Person 存在的弱表)。

简单地说聚合根是可以在没有其他任何东西的情况下识别的对象。一个国家可能没有人而存在,而没有订单则无法识别订单行。您可能想阅读这篇文章:http://dddcommunity.org/library/vernon_2011

关于实体框架,请查看我的 repository/uow 实现:http://blog.gauffin.org/2013/01/repository-pattern-done-right/

【讨论】:

感谢 jgauffin 的回复,这使我对聚合的理解更加清晰。 存储库文章:'更现实的做法是你在 UserRepository.GetUsersGroupOnSomeComplexQuery() 中直接使用 ADO.NET,而在 UserRepository.Create() 中使用 Entity Framework。' 为什么我从来没有考虑过,干杯!

以上是关于存储库模式和聚合根模式和实体框架的主要内容,如果未能解决你的问题,请参考以下文章

领域模型和实体框架之间的存储库模式和映射

使用实体框架、代码优先和 CRUD 操作的存储库模式

使用实体框架 4 和存储库模式的多层架构

具有存储库模式的实体框架 DAL、BLL

多对多实体框架和存储库模式插入/更新

为啥存储库模式在实体框架中被广泛使用,好像它很复杂?