【问题标题】:Incorporating ORM into a (semi) SOA architecture将 ORM 合并到(半)SOA 架构中
【发布时间】:2026-02-12 06:30:01
【问题描述】:

我正在探索 ORM 的产品(专注于 NHibernate,考虑所有选项),并且确信使用 ORM 可能对我们的一些项目有很大的好处——但是我很难想象如何它会在我们的系统中播放。

我的理解是 ORM 理想地用于将数据库和业务逻辑粘合在一起。这假设业务逻辑可以访问数据库,但在我们的系统中,Web 服务卡在中间。

我们当前的系统相当简单。我们一直是 .NET,并且拥有:

  • 数据库。有表格......和行。
    • 权限仅限于对存储过程执行权限,我们通过基本验证构建存储过程,并且在不经过存储过程的情况下不会进出数据库。
  • 网络服务
    • 对数据库存储过程执行 CRUD 操作
    • 目前通常使用 DataSets/DataTables 作为他们的消息
  • 业务逻辑
    • 与网络服务对话

在混合中添加 ORM 似乎合乎逻辑地将其置于数据库和 Web 服务之间。因此客户端会向服务发出请求,服务会使用 ORM 以对象而不是 DataTables 的形式检索结果,并且客户端将从 Web 服务接收对象。

所以我的问题是:

  • 这种方法有效吗?

    • 是否有任何特定的 ORM 支持这种方法?是否有任何主要的 ORM 特别不适合这种环境?
  • 是否有另一种实现将一些 ORM 交互放置在 Web 服务的客户端(让客户端从 ORM 提供者请求一个对象,并让 ORM 提供者包装 Web 服务通信)?

  • 我们当前的工作单元专注于 DataTables 及其行状态跟踪。

    • 当我们在 ORM 和业务逻辑之间插入一个 Web 服务时,它会提供多少状态跟踪?
    • 我们映射的对象是否需要提供自己的状态跟踪?

【问题讨论】:

标签: .net nhibernate architecture orm


【解决方案1】:

您的 Web 服务和存储过程层已经完成了低级别 ORM 将执行的大部分工作:以强类型方式访问数据库。听起来您从 Web 服务中获取了 DataTables,并且您希望将这些 DataTables 封装到类中。

大多数 ORM 产品提供的“自动生成”功能对您的帮助很少,因为它们通常旨在直接从 SQL 源创建类。另一方面,如果您的 Web 服务允许发现返回的列,那么从传统的代码生成技术创建这样的包装类并不是一个困难的项目。如果这些生成的类派生自您的 ORM 的基本类型,您可能能够使用其余的基础设施(实体集合、工作单元等)。

这与我见过的大多数架构都大不相同。我已经看到 DataStore->ORM->Business Logic->Web Service==>Consumer 使用了很多。这使得业务逻辑易于针对数据存储编写,同时提供 Web 服务来决定如何参与业务逻辑。消费者(最终用户的应用程序,桌面或网络演示)主要负责演示(在大多数情况下应该如此)。

另一方面(除非我读错了),您似乎对 DataStore->Sproc->WebServices===>ORM->Business Logic->Consumer 感兴趣。这不是我经常看到的。我认为它不利于您以您正在考虑的方式采用 ORM。

是我遗漏了什么,还是大部分业务逻辑真的在客户端上执行?

【讨论】:

  • 我想“业务逻辑”这个词有点松散。假设我们的应用程序是一个小部件编辑器,我可以在其中从我们的数据库中创建/编辑/删除小部件。在我们的实现中,实际使用该小部件的所有逻辑都是客户端的;唯一的服务器端逻辑是用户身份验证和小部件验证(粗略检查小部件是否违反任何主要数据规则)。客户端获得一个小部件的 DataTable,可以根据需要添加/编辑/删除,此外它还包含完整的验证。
  • 在您的示例中,用户可以定义小部件。这似乎意味着相当少量的小部件相关类携带大量关于特定小部件的使用和状态的自定义数据(这是 DataTable 信息)。由于这个(可能)类的数量很少,如果您想将 DataTable 本身隐藏在一个简单易用的界面后面,那么创建一些外观类可能会更简单......但这将是自定义的,而不是传统的 ORM。
【解决方案2】:

我建议不要在您的情况下使用 ORM,这是来自经常使用 NHibernate 的人。在您当前的设置中,您将不得不跳过几个环节才能让您的应用程序正常工作,并且您将无法从 NHibernate 等优秀 ORM 提供的大多数功能中受益。

  • 虽然可以使用 sprocs 和 ORM,但难以配置和限制 ORM 的功能。
  • 在使用 NHibernate 时,可访问性的持久性是一个巨大的好处,但由于您的域层已“断开连接”,因此您无法使用。
  • NHibernate 基于 IDbConnection,因此尝试通过 Web 服务将其连接到客户端会导致您无法使用 Session(工作单元)

如果您尝试传递对象而不是 DataTables,为什么不使用 DTO 来代替呢?这将为您提供强类型对象,但仍可在您的设置中使用。

【讨论】: