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

ORM 框架新增邏輯:參數化 INSERT 語句建構與效能優化策略 (第 11 講下第 2 部分)

     編輯:關於C語言

InsertObjects 核心實作

public int InsertObjects(IEnumerable objects, string tableName)
{
    if (objects == null) throw new ArgumentNullException("objects");
    CheckBindInfo(objects, false); // 不強制 Key
    ArrayList list = new ArrayList(); foreach (object o in objects) list.Add(o);
    if (list.Count == 0) return 0;

    CheckConnection();
    string lastSql = null; int insertCount = 0;

    using (IDbCommand cmd = conn.CreateCommand())
    {
        foreach (object obj in list)
        {
            TableBindInfo table = GetBindInfo(obj.GetType());
            string targetTable = string.IsNullOrEmpty(tableName) ? table.TableName : tableName;
            ArrayList values = new ArrayList();
            StringBuilder cols = new StringBuilder(), vals = new StringBuilder();

            foreach (FieldBindInfo f in table.Fields)
            {
                if (!f.Property.CanRead) throw new Exception($"屬性 {f.Property.Name} 不可讀");
                object val = f.Property.GetValue(obj, null);
                if (val == null || DBNull.Value.Equals(val)) continue; // 跳過 Null

                if (cols.Length > 0) { cols.Append(", "); vals.Append(", "); }
                cols.Append(FixFieldName(f.FieldName));
                vals.Append("?");
                values.Add(f.ToDataBase(val));
            }
            if (cols.Length == 0) continue;

            string sql = $"INSERT INTO {FixTableName(targetTable)} ({cols}) VALUES ({vals})";

            // SQL 快取優化:相同 SQL 結構重用命令物件參數集合
            if (sql != lastSql)
            {
                lastSql = sql;
                cmd.Parameters.Clear();
                cmd.CommandText = sql;
                for (int i = 0; i < values.Count; i++) cmd.Parameters.Add(cmd.CreateParameter());
            }
            // 填充參數值
            for (int i = 0; i < values.Count; i++)
                ((IDbDataParameter)cmd.Parameters[i]).Value = values[i];

            insertCount += cmd.ExecuteNonQuery();
        }
    }
    return insertCount;
}

效能優化亮點

  • SQL 結構快取:同一實體型別產生相同 SQL 文本時,重用 CommandText 與參數集合結構,僅更新參數值,避免重複 Parameters.Clear/Add 開銷。
  • 參數化:所有值以 ? 佔位符傳遞,防止注入、型別安全。
  • 跳過 Null 值:屬性為 Null 時不納入 INSERT 欄位,由資料庫預設值處理。
  • 可讀性檢查:Property.CanRead 確保屬性可讀取。

介面延伸

基於 InsertObjects 衍生單一物件插入、指定表名插入等多載,豐富框架程式介面。

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