快速 ORM 要求實體類別必須:
class、public、非 abstract。new T() 有效)。public instance、型別為 CLR 基礎型別/string/DateTime。BindFieldAttribute 才納入映射。
private PropertyInfo[] GetBindProperties(Type recordType)
{
if (recordType == null) throw new ArgumentNullException("recordType");
if (!recordType.IsPublic) throw new ArgumentException($"{recordType.FullName} 非公開類型");
if (!recordType.IsClass) throw new ArgumentException($"{recordType.FullName} 非類別");
if (recordType.IsAbstract) throw new ArgumentException($"{recordType.FullName} 不得為抽象類別");
if (recordType.GetConstructor(Type.EmptyTypes) == null)
throw new ArgumentException($"{recordType.FullName} 無預設建構函式");
var list = new ArrayList();
foreach (PropertyInfo p in recordType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
var attr = (BindFieldAttribute)Attribute.GetCustomAttribute(p, typeof(BindFieldAttribute));
if (attr != null)
{
if (p.GetIndexParameters().Length > 0)
throw new ArgumentException($"屬性 {recordType.FullName}.{p.Name} 不得為索引子");
Type pt = p.PropertyType;
if (!(pt.IsPrimitive || pt == typeof(string) || pt == typeof(DateTime)))
throw new ArgumentException($"不支援屬性 {p.Name} 的型別 {pt.FullName}");
list.Add(p);
}
}
if (list.Count == 0) throw new ArgumentException($"{recordType.FullName} 無標記欄位");
return (PropertyInfo[])list.ToArray(typeof(PropertyInfo));
}
private string GetBindFieldName(PropertyInfo p)
{
var attr = (BindFieldAttribute)Attribute.GetCustomAttribute(p, typeof(BindFieldAttribute));
string name = attr.Name?.Trim();
return string.IsNullOrEmpty(name) ? p.Name : name;
}
public override int FillInsertCommand(IDbCommand cmd, object record)
{
// 參數檢查、型別轉換
var emp = (DB_Employees)record;
var fields = new ArrayList(); var values = new ArrayList();
fields.Add("EmployeeID"); values.Add(emp.EmployeeID);
if (emp.LastName != null) { fields.Add("LastName"); values.Add(emp.LastName); }
fields.Add("BirthDate"); values.Add(emp.BirthDate.ToString("yyyy-MM-dd"));
// ... 其他屬性
fields.Add("Sex"); values.Add(emp.Sex);
if (fields.Count == 0) return 0;
cmd.Parameters.Clear();
var sql = new StringBuilder();
sql.Append("INSERT INTO Employees (").Append(ConcatStrings(fields)).Append(") VALUES (");
for (int i = 0; i < values.Count; i++)
{
if (i > 0) sql.Append(", ");
sql.Append(cmd.CreateParameter().ParameterName); // @p0 或 ?
var p = cmd.CreateParameter(); p.Value = values[i]; cmd.Parameters.Add(p);
}
sql.Append(")");
cmd.CommandText = sql.ToString();
return values.Count;
}
RecordORMHelper 定義虛擬方法 FillInsertCommand,動態編譯產生具體實體類別的覆寫實作。ConcatStrings 輔助方法快速連接欄位名稱。