123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Reflection.Emit;
- using System.Reflection;
- using Ant.ORM.Table;
- namespace Ant.ORM.Tool
- {
- /// <summary>
- /// 快速转换类[数据量越大[500条起],性能越高]
- /// </summary>
- internal class FastToT<T>
- {
- public delegate T EmitHandle(MDataRow row);
- /// <summary>
- /// 构建一个ORM实体转换器
- /// </summary>
- /// <typeparam name="T">转换的目标类型</typeparam>
- /// <param name="schema">表数据架构</param>
- public static EmitHandle Create(MDataTable schema)
- {
- Type tType = typeof(T);
- Type rowType = typeof(MDataRow);
- DynamicMethod method = new DynamicMethod("RowToT", tType, new Type[] { rowType }, tType);
- MethodInfo getValue = rowType.GetMethod("GetItemValue", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(int) }, null);
- ILGenerator gen = method.GetILGenerator();
-
- gen.DeclareLocal(tType);
- gen.DeclareLocal(typeof(object));
- gen.DeclareLocal(typeof(bool));
- gen.Emit(OpCodes.Newobj, tType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { }, null));
- gen.Emit(OpCodes.Stloc_0);
- int ordinal = -1;
- foreach (FieldInfo field in tType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
- {
- string fieldName = field.Name.TrimStart('_');
- ordinal = schema.GetOrdinal(fieldName);
- if (ordinal > -1)
- {
- Label retFalse = gen.DefineLabel();
- gen.Emit(OpCodes.Ldarg_0);
- gen.Emit(OpCodes.Ldc_I4, ordinal);
- gen.Emit(OpCodes.Call, getValue);
- gen.Emit(OpCodes.Stloc_1);
- gen.Emit(OpCodes.Ldloc_1);
- gen.Emit(OpCodes.Ldnull);
- gen.Emit(OpCodes.Ceq);
- gen.Emit(OpCodes.Stloc_2);
- gen.Emit(OpCodes.Ldloc_2);
- gen.Emit(OpCodes.Brtrue_S, retFalse);//为null值,跳过
- gen.Emit(OpCodes.Ldloc_0);
- gen.Emit(OpCodes.Ldloc_1);
- EmitCastObj(gen, field.FieldType);
- gen.Emit(OpCodes.Stfld, field);
- gen.MarkLabel(retFalse);//继续下一个循环
- }
- }
- gen.Emit(OpCodes.Ldloc_0);
- gen.Emit(OpCodes.Ret);
- return method.CreateDelegate(typeof(EmitHandle)) as EmitHandle;
- }
- private static void EmitCastObj(ILGenerator il, Type targetType)
- {
- if (targetType.IsValueType)
- {
- il.Emit(OpCodes.Unbox_Any, targetType);
- }
- else
- {
- il.Emit(OpCodes.Castclass, targetType);
- }
- }
- }
- }
|