DeleteObjects 核心實作
public int DeleteObjects(IEnumerable objects)
{
if (objects == null) throw new ArgumentNullException("objects");
CheckBindInfo(objects, true); CheckConnection();
int count = 0;
using (IDbCommand cmd = conn.CreateCommand())
{
foreach (object obj in objects)
{
TableBindInfo table = GetBindInfo(obj.GetType());
ArrayList values = new ArrayList();
string where = BuildCondition(obj, values); // 產生 WHERE 子句
string sql = $"DELETE FROM {FixTableName(table.TableName)} WHERE {where}";
cmd.Parameters.Clear();
cmd.CommandText = sql;
foreach (object v in values)
{
IDbDataParameter p = cmd.CreateParameter();
p.Value = v; cmd.Parameters.Add(p);
}
count += cmd.ExecuteNonQuery();
}
}
return count;
}
BuildCondition 產生 WHERE 子句
private string BuildCondition(object obj, ArrayList values)
{
TableBindInfo table = GetBindInfo(obj.GetType());
StringBuilder sb = new StringBuilder();
foreach (FieldBindInfo f in table.Fields)
{
if (!f.Attribute.Key) continue; // 僅關鍵欄位
object val = f.Property.GetValue(obj, null);
if (val == null || DBNull.Value.Equals(val))
throw new Exception($"關鍵欄位屬性 {f.Property.Name} 未指定值");
if (sb.Length > 0) sb.Append(" AND ");
sb.Append($"{FixFieldName(f.FieldName)} = ?");
values.Add(f.ToDataBase(val));
}
if (sb.Length == 0)
throw new Exception($"類型 {obj.GetType().FullName} 無法產生查詢條件");
return sb.ToString();
}
設計要點
- 僅以
Key=true 的欄位組成 WHERE 條件,支援複合主鍵。
- 參數化 SQL (
? 佔位符) 防止注入,values 列表保持參數順序與 SQL 一致。
FixTableName/FixFieldName 處理保留字與大小寫 (如加方括號 [Column])。
- 缺少關鍵欄位值時主動拋出異常,避免誤刪全表。