首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 發現之旅第十一講:使用反射與特性構建 ORM 框架(下)

     編輯:關於C#

核心資料操作實作:新增、修改、刪除

承接上一講的查詢功能,本講完整實作 ORM 框架的寫入操作,包含 InsertObjects、UpdateObjects、DeleteObjects 三大核心方法,皆採用反射動態組裝 SQL 並搭配參數化查詢,確保安全與效能。

新增資料 InsertObjects

方法接受物件集合與選擇性資料表名稱,流程如下:

  1. 驗證參數與綁定資訊,檢查資料庫連線。
  2. 遍歷每個物件,取得其 TableBindInfo(含資料表名、欄位綁定集合)。
  3. 迭代所有可讀且非 Null 的綁定屬性,收集欄位名與經 FieldBindInfo.ToDataBase() 轉換後的值。
  4. 動態組裝 INSERT INTO Table (欄位...) VALUES (參數...) SQL 字串,參數佔位符依 NamedParameter 設定為 @Param 或 ?。
  5. 使用 strLastSQL 快取上一條 SQL,避免重複設定 IDbCommand 結構,僅更新參數值即可執行,大幅提升批次新增效能。
  6. 呼叫 ExecuteNonQuery 執行,累計影響筆數並回傳。
// 關鍵片段:SQL 組裝與參數綁定
StringBuilder myStr = new StringBuilder("Insert Into " + FixTableName(TableName2) + " (");
StringBuilder myFields = new StringBuilder();
ArrayList values = new ArrayList();
foreach (FieldBindInfo field in table.Fields) {
    object v = field.Property.GetValue(obj, null);
    if (v == null || DBNull.Value.Equals(v)) continue;
    values.Add(field.ToDataBase(v));
    if (myStr.Length > 0) { myStr.Append(", "); myFields.Append(", "); }
    myStr.Append("?"); // 或 @Param
    myFields.Append(FixFieldName(field.FieldName));
}
myStr.Append(") Values (").Append(myFields).Append(")");
// 參數綁定略...

修改資料 UpdateObjects

更新邏輯需構造 SET 子句與 WHERE 條件:

  1. 遍歷物件集合,取得綁定資訊。
  2. 迭代所有綁定欄位,組裝 欄位 = 參數 片段,收集轉換後的值。
  3. 呼叫 BuildCondition 依 Key=true 的關鍵欄位產生 WHERE 條件1 AND 條件2...,若無關鍵欄位則拋出異常。
  4. 合併為完整 UPDATE Table SET ... WHERE ...,清除並重建命令參數,執行更新。
private string BuildCondition(object obj, ArrayList values) {
    StringBuilder mySQL = new StringBuilder();
    foreach (FieldBindInfo field in table.Fields) {
        if (field.Attribute.Key) {
            object v = field.Property.GetValue(obj, null);
            if (v == null || DBNull.Value.Equals(v)) throw new Exception("關鍵欄位未指定值");
            if (mySQL.Length > 0) mySQL.Append(" And ");
            mySQL.Append(FixFieldName(field.FieldName)).Append(" = ?");
            values.Add(field.ToDataBase(v));
        }
    }
    if (mySQL.Length == 0) throw new Exception("無法產生查詢條件");
    return mySQL.ToString();
}

刪除資料 DeleteObjects

刪除較簡單,僅需 WHERE 條件:

  1. 遍歷物件,呼叫 BuildCondition 取得條件 SQL 與參數值。
  2. 組裝 DELETE FROM Table WHERE ...。
  3. 設定命令參數並執行,累計刪除筆數。

實戰應用範例:WinForm 員工管理系統

以 Access 2000 Employees 資料表為例,對應實體 DB_Employees 以特性標記對應關係,EmployeeID 標記為 Key=true。

架構啟動與連線管理

private MyORMFramework CreateFramework() {
    OleDbConnection conn = new OleDbConnection();
    conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" 
        + Path.Combine(Application.StartupPath, "demomdb.mdb");
    conn.Open();
    return new MyORMFramework(conn);
}

查詢與顯示(RefreshList)

private void RefreshList(MyORMFramework myWork) {
    object[] objs = myWork.ReadAllObjects(typeof(DB_Employees));
    ArrayList list = new ArrayList(); list.AddRange(objs);
    this.lstName.DataSource = list;
    this.lstName.DisplayMember = "FullName"; // 顯示衍生屬性
}

列表選取事件直接將 DB_Employees 實例屬性繫結至右側文字方塊,展示 ORM 物件導向優勢。

新增、修改、刪除操作

  • 新增:彈出編輯對話框輸入資料,呼叫 InsertObject 成功後 RefreshList。
  • 修改:取得選取物件,對話框編輯(ID 唯讀),呼叫 UpdateObject 成功後重新整理。
  • 刪除:確認對話框後呼叫 DeleteObject,重新整理列表。

所有操作均採 using 區塊確保連線正確釋放,程式碼簡潔直觀。

框架部署與總結

此 ORM 框架屬輕量級設計,零外部相依,部署極簡單:將專案輸出為 DLL 參考,或直接複製 MyORMFramework.cs 至專案即可使用。

本系列展示如何善用 .NET 反射(程式基因分析)與特性(宣告式標記)構建靈活框架。反射提供執行期型別探測與動態調用能力,特性提供編譯期中繼資料標記,兩者結合實現「約定優於配置」的 ORM 核心邏輯,大幅降低資料存取層開發與維護成本。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved