ORM (Object-Relational Mapping) 物件關聯對映

AdSense

前言

ORM,全名為 Object-Relational Mapping (物件關聯對映),是一種程式設計技術。簡單來說,它就像是一個翻譯員,負責把程式語言的「物件」和資料庫的「關聯式資料」互相對映起來。

有了 ORM,你就可以用 C# 程式碼,直接像操作物件一樣來操作資料庫,而不用再寫一堆繁瑣的 SQL 語法。

為什麼需要 ORM?

在沒有 ORM 之前,我們通常使用像 ADO.NET 這樣的技術來操作資料庫。這需要我們手動寫 SQL 語句,並將資料庫的回傳結果一筆一筆地轉換成程式中的物件。

例如,如果你想從 Students (學生) 資料表中查詢年齡大於 18 歲的學生,程式碼可能會像這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// ADO.NET 傳統寫法
using System.Data.SqlClient;

string connectionString = "你的連線字串";
List<Student> students = new List<Student>();

using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string sql = "SELECT Id, Name, Age FROM Students WHERE Age > 18";
using (SqlCommand command = new SqlCommand(sql, connection))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Student student = new Student
{
Id = reader.GetInt32(0),
Name = reader.GetString(1),
Age = reader.GetInt32(2)
};
students.Add(student);
}
}
}
}

這樣的方式很繁瑣,而且程式碼與 SQL 緊密耦合,如果資料庫結構變動 (例如新增一個欄位),你就需要修改所有相關的 SQL 語句和對應的程式碼,維護起來非常困難。

有了 ORM 之後

ORM 的出現就是為了解決這個問題。它會自動處理資料庫欄位與程式物件屬性的對應,你只需要用物件導向的方式來寫程式,不必關心底層的 SQL 細節。

當你使用 ORM 時,同樣的查詢可以變得非常簡潔,例如使用 Entity Framework (EF)

1
2
3
4
5
6
7
8
// 使用 ORM (Entity Framework Core)
// dbContext 是資料庫上下文物件
var students = dbContext.Students
.Where(s => s.Age > 18)
.ToList();

// ORM 會自動產生並執行類似以下的 SQL 語法:
// SELECT Id, Name, Age FROM Students WHERE Age > 18;

ORM 的核心概念與運作流程

ORM 的運作流程可以分為三個主要步驟:

1. 建立 Mapping (對應)

這是 ORM 的基礎。你需要定義 C# 類別 (物件) 來對應資料庫中的資料表。例如,一個 Student 類別會對應到 Students 資料表,類別的屬性 (Name) 會對應到資料表的欄位 (Name)。

2. ORM 產生 SQL

當你呼叫 ORM 的 API (例如:dbContext.Students.Where(...)) 時,ORM 會根據你設定好的對應規則,自動將你的 C# 程式碼轉換成對應的 SQL 語句。

3. 結果回傳為物件

SQL 語句在資料庫執行後,ORM 會自動將查詢結果轉換回 C# 的物件或物件集合,讓你可以在程式中直接使用。

ORM 就像一個智能翻譯機,負責將你的「物件語言」翻譯成資料庫能理解的「SQL 語言」。

常見的 ORM 框架

在 C# 的世界裡,最廣為人知的 ORM 框架是 Entity Framework (EF)

Entity Framework (EF)

EF 是微軟官方推薦的 ORM,功能非常強大,支援多種資料庫 (SQL Server, MySQL, PostgreSQL 等)。它有兩種主要的開發模式:

  • Code-First:先寫 C# 程式碼模型,再由 EF 自動產生資料庫結構。
  • Database-First:先有資料庫,再由 EF 自動產生對應的 C# 程式碼模型。

LINQ to SQL

這是一個比較早期的微軟 ORM 技術,雖然功能沒有 EF 豐富,但它專門為 SQL Server 設計,在某些較簡單的專案中仍可使用。不過,對於新的專案,通常會建議優先使用 Entity Framework

其他

語言 常見 ORM 工具
C# / .NET Entity Framework (EF Core)、NHibernate、Dapper (微型 ORM)
Java Hibernate、MyBatis
Python SQLAlchemy、Django ORM
JavaScript / Node.js Sequelize、TypeORM、Prisma
PHP Doctrine、Eloquent (Laravel)

ORM 的優點與缺點

優點

  • 提高開發效率:不用手寫繁瑣的 SQL 語法,程式碼更簡潔。
  • 程式碼更易於維護:當資料庫結構變動時,你只需要更新物件模型,不用到處修改 SQL 語句。
  • 提高安全性:ORM 會自動處理參數化查詢,有效防止 SQL Injection 攻擊。
  • 程式碼可讀性高:用 LINQ 語法查詢資料就像操作 C# 集合一樣,語意更清晰。

缺點

  • 效能開銷:ORM 產生的 SQL 語句可能不如手寫的 SQL 來得最佳化,特別是在處理複雜的查詢時。
  • 學習成本:你需要花時間學習 ORM 本身的規範與使用方式,而不是直接寫 SQL。
  • 除錯困難:當 ORM 產生的 SQL 語法出錯時,可能需要額外的工具來追蹤和除錯。

簡單範例:EF Core ORM

1. 建立模型

1
2
3
4
5
6
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}

2.操作資料

新增資料

1
2
3
var student = new Student { Name = "John", Age = 20 };
dbContext.Students.Add(student);
dbContext.SaveChanges();

產生的 SQL:

1
INSERT INTO Students (Name, Age) VALUES ('John', 20);

查詢資料

1
var students = dbContext.Students.Where(s => s.Age > 18).ToList();

產生的 SQL:

1
SELECT Id, Name, Age FROM Students WHERE Age > 18;

總結

總體而言,ORM 是一種現代軟體開發中非常重要的技術。它透過抽象化底層的資料庫操作,讓開發者能更專注於商業邏輯,從而提升開發效率和程式碼的維護性。對於絕大多數的應用程式開發,ORM 的優點遠大於其缺點。