# 如何通过 ORM 实现从面向数据库编程到面向对象编程的转变

# 问题

  • 项目分页采用 Row_Number() 的方式,而 EF 采用的 Offset/Fecth 方式能提升至少一版的效率

    参看文献 (opens new window)

  • 项目很多联表查询的地方没有建立索引
  • 糟糕的sql
    • 错误的使用联表查询
      -- 错误,无法使用 FORMID 的索引
      LEFT JOIN Proc_DG_Project_Registry dg WITH ( NOLOCK ) ON offer.Project_Id = CAST(dg.FORMID AS NVARCHAR(128))
      -- 应该这样
      LEFT JOIN Proc_DG_Project_Registry dg WITH ( NOLOCK ) ON TRY_CONVERT(uniqueidentifier,offer.Project_Id) is not null AND TRY_CONVERT(uniqueidentifier,offer.Project_Id)=dg.FORMID
      
    • 超长难以理解的视图代码和存储过程
    • 代码中难以维护的sql语句

# 背景

在很多长期运行的老管理系统中,会存在一个现象,就是基于数据库功能编程,重度使用视图、存储过程、代理任务等。

  • 而这些基于数据库的变更,又没法通过版本管理工具来控制,每次发版都要发开人员精心核对数据库结构变化,手动同步这些变化。
  • 另外这些绑定数据库的操作,也制约了数据库的性能,是的更换数据库厂家或者水平伸缩都更加困难。
  • 此外,这种基于数据库的编程思路,往往会忽略面向对象的思想,导致在很多地方无法用继承、多态来解决相似功能代码复用和区分的问题。

# 什么是 ORM

简单说,ORM 就是通过实例对象的语法,完成关系型数据库的操作的技术,是"对象-关系映射"(Object/Relational Mapping) 的缩写。

Relational Object
数据库的表(table) 类(class)
记录(record,行数据) 对象(object)
字段(field) 对象的属性(property)

# 什么是 Code First

Code First 是一种开发方法论,它指的是在应用程序中首先定义和编写实体模型类,然后通过这些实体类自动生成数据库架构(表、列、关系等)。换句话说,Code First 基于代码来定义数据库模型。相对于 Code First,Db First 是另一种开发方法,它是先根据已有的数据库架构生成实体模型类。

# 为什么我们应该采用 Code First 的 ORM 开发方式

使用 ORM 相比传统的SQL有以下几个优势:

  • 抽象化数据库操作

ORM通过将数据库表映射为对象模型,将数据库操作抽象化为面向对象的方式。这样,开发人员可以使用类和方法来操作数据,而不必编写性能不佳的 SQL 语句。这种抽象化使得代码更易读、易维护,并且减少了与数据库相关的底层细节。

同时 Code First 的方式可以将 .NET 类型层次结构映射到数据库,这允许你像往常一样使用基类型和派生类型在代码中编写 .NET 实体。

  • 更高的代码可读性

使用ORM可以使代码更加可读,因为它允许开发人员使用面向对象的编程模型来操作数据。ORM的方法和属性命名通常与业务逻辑更相关,因此可以提高代码的可读性和可维护性。而且数据结构的变化可以通过版本管理工具准确记录,方便问题定位和修复。

  • 减少重复代码

ORM框架提供了许多通用的数据库操作方法,开发人员无需编写重复的SQL代码,从而提高了开发效率。而且字段变更无需修改sql语句,模型变更就能直接体现,维护性更好。

  • 更好的安全性和性能

很多情况 ORM 工具生成的 sql 代码会比徒手编写的 sql 具有更好的性能和安全性。ORM 有现成的工具,很多功能都可以自动完成,比如数据消毒、预处理、事务等等,有效的避免的sql注入、并发锁等问题。

  • 数据库迁移和版本控制

ORM框架通常提供数据库迁移和版本控制的功能。通过 Code First 的方式,使得开发人员可以直接修改实体类来反映业务需求变化,而无需手动编写和执行SQL脚本。ORM框架可以自动检测模型的变化,并生成和执行相应的数据库迁移脚本,从而简化了数据库的版本控制和升级过程。

  • 跨数据库平台支持

避免了数据库的重度依赖,方便缓存的加入和数据库的水平扩展。ORM框架通常具有对多种数据库系统的支持,如MySQL、PostgreSQL、Oracle等。这使得开发人员能够在不同的数据库系统之间进行切换,而无需更改底层的数据库访问代码。这种跨数据库平台支持提供了更大的灵活性和可移植性。

# 怎么做

  • 对于 .net 项目,可以采用 EFCore / EF7 的 code first 模式。先编写对象模型,通过 EF 反向生成迁移数据库 sql 和数据库结构。

EFCore 文档 (opens new window)

  • 对于客户各个部门相同业务不同需求的特性,可以使用 Modal 和 Service 的继承和多态来实现相同业务共用,不同细节区别实现。
最后更新: 6/26/2024, 2:45:18 AM