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

快速 ORM 框架動態生成程式碼:InnerReadRecord 方法自動產生與型別轉換邏輯 (第 12 講上第 8 部分)

     編輯:關於C語言

動態生成 InnerReadRecord 程式碼片段


writer.WriteLine("// 從資料讀取器讀取資料建立物件");
writer.WriteLine("protected override object InnerReadRecord(IDataReader reader, int[] FieldIndexs)");
writer.BeginGroup("{");
writer.WriteLine($"{recordType.FullName} record = new {recordType.FullName}();");
writer.WriteLine("int index = 0;");

for (int i = 0; i < ps.Length; i++)
{
    PropertyInfo p = ps[i];
    if (!p.CanWrite) continue;

    var attr = (BindFieldAttribute)Attribute.GetCustomAttribute(p, typeof(BindFieldAttribute));
    writer.WriteLine("");
    writer.WriteLine($"index = FieldIndexs[{i}]; // 讀取欄位 {GetBindFieldName(p)}");
    writer.WriteLine("if (index >= 0)");
    writer.BeginGroup("{");
    Type pt = p.PropertyType;
    object defVal = GetDefaultValue(p);
    string readExpr = null;

    if (pt == typeof(byte))
        readExpr = $"ConvertToByte(reader.GetValue(index), {GetValueString(pt, defVal)})";
    else if (pt == typeof(sbyte))
        readExpr = $"ConvertToSByte(reader.GetValue(index), {GetValueString(pt, defVal)})";
    else if (pt == typeof(short))
        readExpr = $"ConvertToInt16(reader.GetValue(index), {GetValueString(pt, defVal)})";
    // ... 其他基本型別 ConvertToXxx
    else if (pt == typeof(DateTime))
    {
        string defStr = "DateTime.MinValue";
        DateTime dt = Convert.ToDateTime(defVal);
        if (dt != DateTime.MinValue) defStr = $"new DateTime({dt.Ticks})";
        readExpr = $"ConvertToDateTime(reader.GetValue(index), {defStr}, {attr.ReadFormat == null ? "null" : $"\"{attr.ReadFormat}\""})";
    }
    else if (pt == typeof(string))
        readExpr = $"ConvertToString(reader.GetValue(index), {defVal == null ? "null" : $"@\"{defVal}\""})";
    else if (pt == typeof(char))
        readExpr = $"ConvertToChar(reader.GetValue(index), {GetValueString(pt, defVal)})";
    else
        throw new InvalidOperationException($"不支援屬性型別 {p.Name} {pt.FullName}");

    writer.WriteLine($"record.{p.Name} = {readExpr};");
    writer.EndGroup("}");
}
writer.WriteLine("");
writer.WriteLine("return record;");
writer.EndGroup("}// InnerReadRecord");

生成策略說明

  • 使用 XmlTextWriter/StringWriter 等程式碼產生輔助類別 (writer.BeginGroup/EndGroup 自動縮排)。
  • 為每個可寫屬性產生 if (index >= 0) 區塊,呼叫對應 ConvertToXxx 靜態方法處理 DBNull、型別轉換、格式化。
  • DateTime 特殊處理:支援 ReadFormat (如 yyyyMMdd) 並以 DateTime.ParseExact 解析。
  • 產生的程式碼最終經 CSharpCodeProvider 編譯成組件快取,運行期直接呼叫強型別方法,零反射開銷。

核心優勢

將反射掃描、型別檢查、程式碼生成前置於啟動/首次使用階段,運行期熱路徑為直接方法呼叫,大幅提升大量資料讀取效能。

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