using System; using System.Collections.Generic; using System.Text; using System.Reflection.Emit; using System.Reflection; using CYQ.Data.Table; namespace CYQ.Data.Tool { /// /// 快速转换类[数据量越大[500条起],性能越高] /// internal class FastToT { public delegate T EmitHandle(MDataRow row); /// /// 构建一个ORM实体转换器 /// /// 转换的目标类型 /// 表数据架构 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();//开始编写IL方法。 gen.DeclareLocal(tType); gen.DeclareLocal(typeof(object)); gen.DeclareLocal(typeof(bool)); //分别定义了一个Type t,object o,bool b; gen.Emit(OpCodes.Newobj, tType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { }, null)); gen.Emit(OpCodes.Stloc_0);//t= new T(); int ordinal = -1; List fileds = new List(); fileds.AddRange(tType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)); if (tType.BaseType.Name != "Object" && tType.BaseType.Name != "OrmBase") { FieldInfo[] items = tType.BaseType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); foreach (FieldInfo item in items) { bool isAdd = true; foreach (FieldInfo f in fileds)//这里检测去重复。 { if (item.Name == f.Name) { isAdd = false; break; } } if (isAdd) { fileds.Add(item); } } } foreach (FieldInfo field in fileds) { string fieldName = field.Name; if(fieldName[0]=='<') { fieldName=fieldName.Substring(1,fieldName.IndexOf('>')-1); } ordinal = schema.Columns.GetIndex(fieldName.TrimStart('_')); if (ordinal == -1) { ordinal = schema.Columns.GetIndex(fieldName); } if (ordinal > -1) { Label retFalse = gen.DefineLabel();//定义标签;goto; gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldc_I4, ordinal); gen.Emit(OpCodes.Call, getValue);//Call GetItemValue(ordinal); gen.Emit(OpCodes.Stloc_1); // o=GetItemValue(ordinal); gen.Emit(OpCodes.Ldloc_1); gen.Emit(OpCodes.Ldnull); gen.Emit(OpCodes.Ceq);// if (o==null) gen.Emit(OpCodes.Stloc_2); //b=o==null; 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);//对实体赋值 System.Object.FieldSetter(String typeName, String fieldName, Object val) 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); } } } }