【问题标题】:EF6 and Onion architecture - database first and without Repository patternEF6 和 Onion 架构 - 数据库优先且无存储库模式
【发布时间】:2023-04-10 13:04:02
【问题描述】:

我正在尝试将所有这些组合在一起,为现有应用程序构建一个新架构。现有应用程序有很多业务逻辑,所以我认为 Onion 架构(或类似的东西 - 分层、解耦)可能是正确的解决方案 - http://jeffreypalermo.com/blog/the-onion-architecture-part-1/

我看到的所有示例都在基础架构层(或 DAL,或任何实际连接到数据库的层)中使用 Repo/UoW(顶部或 ORM)模式。但我不确定在我的情况下是否需要 Repo/UoW(在 EF 之上),因为:

  • EF6 可以在没有 Repo 模式的情况下很好地进行单元测试,像这样实现有界 DbContexts - http://msdn.microsoft.com/en-us/library/dn314429.aspx

  • 大多数通用 Repo 示例倾向于使用泄漏抽象,因为它们公开了接受 LINQ 查询的方法(如 Expression> 查询)

  • 非泛型 Repos 往往会导致大量代码

所以这里有几个问题:

1) 大多数示例首先使用 EF 代码,核心层使用 POCO 对象,但我必须先使用数据库并生成模型。我可以在 Core 中使用 EF 生成的 .edmx 模型,还是这会对数据访问造成不必要的耦合?有没有办法从 EF 生成的数据访问代码(context.tt 文件等)中拆分 EF 生成的类(带有表字段的 .cs 文件)?

2)我打算像这样实现服务层(有界的 DbContext 接口作为依赖项传递)

public class OrderService(IMyDbContext) { ... } 

这意味着,将使用 DbSet 的 DbContext 包装器接口代替存储库接口。可以使用模拟 IMyDbContext 和模拟 IDataSet 来完成单元测试。 这不是打败了抽象数据库的整个概念吗?在我看来,这对于单元测试来说已经足够了,但是从架构的角度来看这可以吗?我是否错过了 Repo/UoW(在 EF 之上)模式提供的一些很棒的功能?

3)似乎存储库的一种替代方法(虽然不是很流行)是查询对象: http://www.wekeroad.com/2014/03/04/repositories-and-unitofwork-are-not-a-good-idea/

http://lostechies.com/jimmybogard/2012/10/08/favor-query-objects-over-repositories/

但我还没有真正找到任何有关 Onion + Query Objects 的示例。这可能是 Repository 接口层的合理选择吗?将查询接口放在那里,而将查询实现放在接口(数据访问)层?我应该将所有数据访问逻辑放在 QueryObjects 中吗?如果我直接在 Coltroller/Service 层使用 DbContext.Where 查询,这是否会在数据访问和业务逻辑之间造成不必要的耦合?

【问题讨论】:

  • 您的问题虽然有趣且相关,但对于 StackOverflow 问答格式而言过于宽泛。
  • 或许这个Q更适合codereview.stackexchange.com

标签: entity-framework onion-architecture


【解决方案1】:

@andree

我有几个 cmets 可以添加到这个讨论中。我很欣赏这是一个较旧的线程,但我认为讨论仍然很有价值。

首先,我现在建议不要使用 EDMX 文件,因为未来对 EF7 的所有讨论似乎都表明 EDMX 将被删除。 相反,从 EF6.1 开始,您现在可以从现有数据库生成“代码优先”样式配置。

“代码优先”可能应该重命名为“流利配置”

大多数通用 Repo 示例倾向于使用泄漏抽象,因为它们公开了接受 LINQ >查询(如 Expression> 查询)的方法

非泛型 Repos 往往会导致大量代码

我通常发现,稍微“漏点”会很有用。我们使用共享 IQueryable 的存储库,以便轻松编写快速查询 - 但通常使用的任何内容都会正确地移动到存储库中。显然,这会使持久层更难换成其他无法为您提供 IQueryable 的东西,但实际上这从未发生在我身上。

我对“非通用 Repos 往往会导致大量代码”问题的处理方法是使用带有 .tt 模板的代码生成。 - tt 模板生成一堆部分存储库实现和接口。 - 然后,在你自己的部分文件中添加你自己的方法。

请看一下这个库:
http://www.sswdataonion.com
(免责声明:我是这方面的开发人员之一)
它包含用于生成存储库和工作单元模式的 tt 模板。

就个人而言,如果我要编写一个真正不可知论的“无泄漏”服务层,我可能会将其编写为存储库/工作单元模式之上的一个层。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-11
    • 2019-08-27
    • 1970-01-01
    • 2012-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多