ZhiYeJianKang_PeiXun/cyqdata-master/Table/FastToT.cs

239 lines
9.7 KiB
C#
Raw Normal View History

2025-02-20 15:41:53 +08:00
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection.Emit;
using System.Reflection;
using CYQ.Data.Table;
namespace CYQ.Data.Tool
{
//internal class FastToT<T> : FastToT
//{
// private static MDictionary<string, EmitTHandle> emitTHandleDic = new MDictionary<string, EmitTHandle>();
// public delegate T EmitTHandle(MDataRow row);
// public static EmitTHandle Create()
// {
// return Create(null);
// }
// public static EmitTHandle Create(MDataColumn schema)
// {
// Type t = typeof(T);
// string key = t.FullName + (schema == null ? "" : schema.GetHashCode().ToString());
// if (emitTHandleDic.ContainsKey(key))
// {
// return emitTHandleDic[key];
// }
// else
// {
// DynamicMethod method = CreateMethod(t, schema);
// EmitTHandle handle = method.CreateDelegate(typeof(EmitTHandle)) as EmitTHandle;
// emitTHandleDic.Add(key, handle);
// return handle;
// }
// }
//}
/// <summary>
/// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>[<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><D4BD>[500<30><30><EFBFBD><EFBFBD>],<2C><><EFBFBD><EFBFBD>Խ<EFBFBD><D4BD>]
/// </summary>
internal class FastToT
{
private static MDictionary<string, EmitHandle> emitHandleDic = new MDictionary<string, EmitHandle>();
public delegate object EmitHandle(MDataRow row);
public static EmitHandle Create(Type t)
{
return Create(t, null);
}
public static EmitHandle Create(Type t, MDataColumn schema)
{
string key = t.FullName + (schema == null ? "" : schema.GetHashCode().ToString());
if (emitHandleDic.ContainsKey(key))
{
return emitHandleDic[key];
}
else
{
DynamicMethod method = CreateMethod(t, schema);
EmitHandle handle = method.CreateDelegate(typeof(EmitHandle)) as EmitHandle;
emitHandleDic.Add(key, handle);
return handle;
}
//DynamicMethod method = CreateMethod(t, schema);
//return method.CreateDelegate(typeof(EmitHandle)) as EmitHandle;
}
/// <summary>
/// <20><EFBFBD><E6B4A2>̬<EFBFBD><CCAC><EFBFBD><EFBFBD>
/// </summary>
private static MDictionary<string, DynamicMethod> dynamicMethodDic = new MDictionary<string, DynamicMethod>();
/// <summary>
/// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ORMʵ<4D><CAB5>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD>ι<EFBFBD><CEB9><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>
/// </summary>
/// <param name="tType">ת<><D7AA><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="schema"><3E><><EFBFBD><EFBFBD><EFBFBD>ݼܹ<DDBC></param>
internal static DynamicMethod CreateMethod(Type tType, MDataColumn schema)
{
string key = tType.FullName + (schema == null ? "" : schema.GetHashCode().ToString());
if (dynamicMethodDic.ContainsKey(key))
{
return dynamicMethodDic[key];
}
#region <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Type rowType = typeof(MDataRow);
Type toolType = typeof(ConvertTool);
DynamicMethod method = new DynamicMethod("RowToT", tType, new Type[] { rowType }, tType);
MethodInfo getValue = null;
if (schema == null)
{
getValue = rowType.GetMethod("GetItemValue", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(string) }, null);
}
else
{
getValue = rowType.GetMethod("GetItemValue", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(int) }, null);
}
MethodInfo changeType = toolType.GetMethod("ChangeType", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(object), typeof(Type) }, null);
ILGenerator gen = method.GetILGenerator();//<2F><>ʼ<EFBFBD><CABC>дIL<49><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
gen.DeclareLocal(tType);//0
gen.DeclareLocal(typeof(object));//1
gen.DeclareLocal(typeof(bool)); //2 <20>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> ʵ<>壺Type t,<2C><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>object o,ֵ<>Ƿ<EFBFBD>ΪNull<6C><6C>bool b<><62>ֵ<EFBFBD><D6B5><EFBFBD>ͣ<EFBFBD>Type
gen.DeclareLocal(typeof(Type));//3
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<FieldInfo> fileds = new List<FieldInfo>();
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)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD>ظ<EFBFBD><D8B8><EFBFBD>
{
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] == '<')//<ID>k__BackingField
{
fieldName = fieldName.Substring(1, fieldName.IndexOf('>') - 1);
}
if (schema != null)
{
ordinal = schema.GetIndex(fieldName.TrimStart('_'));
if (ordinal == -1)
{
ordinal = schema.GetIndex(fieldName);
}
}
if (schema == null || ordinal > -1)
{
Label retFalse = gen.DefineLabel();//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǩ<EFBFBD><C7A9>goto;
gen.Emit(OpCodes.Ldarg_0);//<2F><><EFBFBD>ò<EFBFBD><C3B2><EFBFBD>0 <20><>row <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ 0 <20><><EFBFBD>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD>ϡ<EFBFBD>
if (schema == null)
{
gen.Emit(OpCodes.Ldstr, fieldName);//<2F><><EFBFBD>ò<EFBFBD><C3B2><EFBFBD>ֵ<EFBFBD><D6B5>string <20><><EFBFBD>Ͷ<EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD><EFBFBD>д洢<D0B4><E6B4A2><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><C2B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>á<EFBFBD>
}
else
{
gen.Emit(OpCodes.Ldc_I4, ordinal);//<2F><><EFBFBD>ò<EFBFBD><C3B2><EFBFBD>ֵ<EFBFBD><D6B5>1 int <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E1B9A9> int32 <20><><EFBFBD>͵<EFBFBD>ֵ<EFBFBD><D6B5>Ϊ int32 <20><><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD>ϡ<EFBFBD>
}
gen.Emit(OpCodes.Call, getValue);//Call GetItemValue(ordinal);=> invoke(row,1)
gen.Emit(OpCodes.Stloc_1); // o=GetItemValue(ordinal); <20>Ӽ<EFBFBD><D3BC><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰֵ<C7B0><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6B4A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1 <20><><EFBFBD>ľֲ<C4BE><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1>С<EFBFBD>
gen.Emit(OpCodes.Ldloc_1);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1 <20><><EFBFBD>ľֲ<C4BE><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD>ϡ<EFBFBD>
gen.Emit(OpCodes.Ldnull);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>O <20><><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD>ϡ<EFBFBD>
gen.Emit(OpCodes.Ceq);// if (o==null) <20>Ƚ<EFBFBD><C8BD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD>ȣ<EFBFBD><C8A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ 1 (int32) <20><><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD>򣬽<EFBFBD> 0 (int32) <20><><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD>ϡ<EFBFBD>
gen.Emit(OpCodes.Stloc_2); //b=(o==null); <20>Ӽ<EFBFBD><D3BC><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰֵ<C7B0><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6B4A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2 <20><><EFBFBD>ľֲ<C4BE><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1>С<EFBFBD>
gen.Emit(OpCodes.Ldloc_2);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2 <20><><EFBFBD>ľֲ<C4BE><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD>ϡ<EFBFBD>
gen.Emit(OpCodes.Brtrue_S, retFalse);//Ϊnullֵ<6C><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> value Ϊ true<75><65><EFBFBD>ǿջ<C7BF><D5BB><EFBFBD><EFBFBD><EFBFBD>򽫿<EFBFBD><F2BDABBF><EFBFBD>ת<EFBFBD>Ƶ<EFBFBD>Ŀ<EFBFBD><C4BF>ָ<EFBFBD><EFBFBD≯<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>
//-------------<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>o=ConvertTool.ChangeType(o, t);
gen.Emit(OpCodes.Nop);//<2F><><EFBFBD><EFBFBD><EFBFBD>޲<EFBFBD><DEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBA3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<20><><EFBFBD>ܿ<EFBFBD><DCBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD>δִ<CEB4><D6B4><EFBFBD>κ<EFBFBD><CEBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>
gen.Emit(OpCodes.Ldtoken, field.FieldType);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҿ<EFBFBD><D2BF><EFBFBD><EFBFBD>е<EFBFBD><D0B5>á<EFBFBD><C3A1><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD>ݱ<EFBFBD><DDB1><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ʾ<EFBFBD><CABE>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD>ϡ<EFBFBD>
gen.Emit(OpCodes.Stloc_3);
gen.Emit(OpCodes.Ldloc_1);//o
gen.Emit(OpCodes.Ldloc_3);
gen.Emit(OpCodes.Call, changeType);//Call ChangeType(o,type);=> invoke(o,type) <20><><EFBFBD><EFBFBD><EFBFBD>ɴ<EFBFBD><C9B4>ݵķ<DDB5><C4B7><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD>ָʾ<D6B8>ķ<EFBFBD><C4B7><EFBFBD><EFBFBD><EFBFBD>
gen.Emit(OpCodes.Stloc_1); // o=GetItemValue(ordinal);
//-------------------------------------------
gen.Emit(OpCodes.Ldloc_0);//ʵ<><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>obj
gen.Emit(OpCodes.Ldloc_1);//<2F><><EFBFBD>Ե<EFBFBD>ֵ objvalue
EmitCastObj(gen, field.FieldType);//<2F><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>
gen.Emit(OpCodes.Stfld, field);//<2F><>ʵ<EFBFBD>帳ֵ System.Object.FieldSetter(String typeName, String fieldName, Object val)
gen.MarkLabel(retFalse);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ѭ<EFBFBD><D1AD>
}
}
gen.Emit(OpCodes.Ldloc_0);
gen.Emit(OpCodes.Ret);
#endregion
dynamicMethodDic.Add(key, method);
return method;
//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);
}
}
/* Emit <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD>ͣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
public ETable RowToT(MDataRow row)
{
Type ttt = typeof(Int32);
Type t = ttt;
ETable et;
object o;
bool b;
et = new ETable();
label:
//ѭ<><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɡ<EFBFBD>
o = row.GetItemValue(0);
if (o == null)
{
goto label;
}
o = ConvertTool.ChangeType(o, t);
et.ID = (int)o;
return et;
}
*/
}
}