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

快速 ORM 框架反射分析:GetBindProperties 取得可繫結屬性與型別檢查 (第 12 講上第 9 部分)

     編輯:關於C語言

InnerReadRecord 動態生成邏輯 (前置說明)

自動產生的 InnerReadRecord 利用 FieldIndexs 映射表 (陣列索引 → reader 欄位序號),將資料從 IDataReader 複製到實體屬性。GetDefaultValue 取得屬性預設值,GetValueString 將值轉為 C# 程式碼常值表示。

GetBindProperties 完整實作


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();
    PropertyInfo[] props = recordType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
    foreach (PropertyInfo p in props)
    {
        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))
                list.Add(p);
            else
                throw new ArgumentException($"不支援屬性 {recordType.FullName}.{p.Name} 的資料類型 {pt.FullName}");
        }
    }
    if (list.Count == 0)
        throw new ArgumentException($"類型 {recordType.FullName} 沒有標記為繫結到任何欄位");
    return (PropertyInfo[])list.ToArray(typeof(PropertyInfo));
}

驗證規則總結

檢查項目失敗時例外
型別為 nullArgumentNullException
非 publicArgumentException
非 class (如 struct/interface)ArgumentException
abstractArgumentException
無 public 無參建構函式ArgumentException
屬性為索引子ArgumentException
屬性型別不在白名單ArgumentException
無任何 BindFieldAttribute 屬性ArgumentException

後續動態生成

取得 PropertyInfo[] 後,框架為每個屬性產生對應的 ConvertToXxx 呼叫程式碼 (見第 8 部分),最終編譯成強型別 InnerReadRecord 方法。

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