我计划创建一个具有以下层的应用程序,并使用实体框架作为我的ORM:
我看过相当多的在线教程,以及与实体框架相关的文章,并看到了DbContextScope项目,它似乎是一个非常好的解决方案,可以控制‘业务事务’,并确保所有相关的更改都提交或回滚。见GitHub:https://github.com/mehdime/DbContextScope
该GitHub存储库中的演示包含在数据库中创建新实体的场景。当我试图将该场景映射到我的层时,它似乎如下所示:
在演示中,在创建DTO时,已经知道正在存储的实体的ID。但是,一旦在业务层调用了SaveChanges()方法,我正在寻找一种方法来确定由EF自动分配的ID。由于此时我处于业务层,因此无法访问该实体,因此无法再访问该实体的ID属性。
我想我只能通过查询刚刚创建的记录来确定ID,但是只有当原始DTO包含一些唯一的标识符来查询数据库时,才能确定ID。但是,如果我在我的DTO中没有一个唯一的值,我可以用来查询呢?
对于如何解决这个问题,有什么建议吗?或者您是否推荐了一种我的层的替代方法?(例如,在业务层使用实体-尽管这听起来是错误的做法)
发布于 2019-04-21 05:21:43
我在任何可能的地方使用Mehdime的上下文范围,因为我发现它是一个特殊的工作单元实现。我同意卡米洛关于不必要的分离的评论。如果EF被信任作为您的DAL,那么应该信任它按照设计的方式工作,这样您就可以完全利用它。
在我的例子中,我的控制器管理DbContextScope,我使用存储库模式,并为我的实体设计DDD。存储库充当与上下文交互的门守护者,其作用域为DbContextLocator并位于上下文中。在创建实体时,存储库作为工厂使用"Create {X}“方法,其中{X}表示实体。这将确保提供创建实体所需的所有信息,并且该实体在返回之前与DbContext相关联,从而保证该实体始终处于有效状态。这意味着进行上下文范围SaveChanges调用时,边界服务具有自动分配ID的实体。ViewModels /DTO是控制器返回给使用者的内容。您还可以选择在SaveChanges边界内调用DbContext的DbContextScope,这也将显示上下文作用域SaveChanges之前的ID。这是一个非常边缘的场景,当您想要为松散耦合的实体获取ID时。(无FK/映射关系)存储库还为“删除”代码提供服务,以确保管理所有相关实体、规则等。虽然编辑实体属于实体本身的DDD方法。
可能有一种更纯粹的观点认为,这种“泄露”域的细节或EF特定的关注点给控制器,但我个人的观点是,在服务层的有限上下文范围内,“信任”实体和EF的好处远远大于其他任何东西。它更简单,并且允许您在代码中具有很大的灵活性,而不需要传播几乎重复的方法来向使用者提供经过过滤的数据,也不需要复杂的过滤逻辑来“隐藏”服务层中的EF。我遵循的基本规则是,实体永远不会在其上下文范围的边界之外返回。(不分离/重新附加,只需选择到ViewModels,并根据传递的视图模型/参数管理实体的创建/更新/删除。)
如果您可以提供更多具体的关注/示例,请随意添加一些代码,概述您看到这些问题的地方。
https://stackoverflow.com/questions/55776657
复制相似问题