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

C# 發現之旅第十二講:ORM 代碼生成器刪除命令實作細節

     編輯:關於C語言

關鍵字段掃描與 WHERE 子句生成

代碼生成器遍歷所有屬性,透過 BindFieldAttribute.Key 識別主鍵欄位,並建立對應的 SQL 參數名稱與 WHERE 條件字串:

ArrayList keyProps = new ArrayList();
ArrayList keyParamNames = new ArrayList();
StringBuilder whereSql = new StringBuilder();

for (int i = 0; i < ps.Length; i++) {
    PropertyInfo p = ps[i];
    if (!p.CanRead) continue;
    BindFieldAttribute fa = (BindFieldAttribute)Attribute.GetCustomAttribute(p, typeof(BindFieldAttribute));
    if (!fa.Key) continue;

    string fieldName = GetBindFieldName(p);
    if (whereSql.Length > 0) whereSql.Append(" AND ");
    keyProps.Add(p);

    if (bolNamedParameter) {
        string pName = "Key" + p.Name;
        keyParamNames.Add(pName);
        whereSql.Append(FixFieldName(fieldName) + " = @" + pName + " ");
    } else {
        whereSql.Append(FixFieldName(fieldName) + " = ? ");
    }
}

FillDeleteCommand 完整生成邏輯

若無關鍵屬性,輸出拋出異常代碼;否則生成參數檢查、實體轉型、SQL 指派、參數綁定等完整流程:

writer.WriteLine("public override int FillDeleteCommand(IDbCommand cmd, object objRecord)");
writer.BeginGroup("{");
if (keyProps.Count == 0) {
    writer.WriteLine("throw new NotSupportedException(\"FillDeleteCommand\");");
} else {
    writer.WriteLine("if (cmd == null) throw new ArgumentNullException(\"cmd\");");
    writer.WriteLine("if (objRecord == null) throw new ArgumentNullException(\"objRecord\");");
    writer.WriteLine($"{recordType.FullName} myRecord = objRecord as {recordType.FullName};");
    writer.WriteLine($"if (myRecord == null) throw new ArgumentException(\"must type '{recordType.FullName}'\");");

    StringBuilder deleteSql = new StringBuilder();
    deleteSql.Insert(0, "DELETE FROM " + tableName + " WHERE " + whereSql);
    writer.WriteLine("cmd.Parameters.Clear();");
    writer.WriteLine($"cmd.CommandText = @\"{deleteSql}\";");
    writer.WriteLine("IDbDataParameter parameter = null;");

    for (int idx = 0; idx < keyProps.Count; idx++) {
        PropertyInfo p = (PropertyInfo)keyProps[idx];
        writer.WriteLine("parameter = cmd.CreateParameter();");
        WriteSetParameterValue(p, writer);
        if (bolNamedParameter) {
            writer.WriteLine($"parameter.ParameterName = \"{keyParamNames[idx]}\";");
        }
        writer.WriteLine("cmd.Parameters.Add(parameter);");
    }
    writer.WriteLine($"return {keyProps.Count};");
}
writer.EndGroup("}");

參數值寫入策略

WriteSetParameterValue 依型別處理:

  • DateTime:使用 BindFieldAttribute.WriteFormat 或預設格式 yyyy-MM-dd HH:mm:ss。
  • string:空值轉 DBNull.Value。
  • 其他:直接指派。

設計考量

  1. 延遲驗證:僅在實際呼叫 FillDeleteCommand 時檢查主鍵存在性,允許無主鍵實體用於查詢/新增。
  2. 參數命名一致性:WHERE 條件與參數名稱同步生成,確保對應正確。
  3. 程式碼可讀性:使用 IndentTextWriter 產生縮排整齊的代碼,利於除錯與維護。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved