/// <summary> /// 使用反射 /// </summary> /// <param name="reader"></param> /// <returns></returns> public static T ReflectDeserialize(IDataReader reader) { DbFieldReader dbReader = new DbFieldReader(reader); var columnList = Enumerable.Range(0, reader.FieldCount).Select(ordinal => { Type fieldType = reader.GetFieldType(ordinal); return(new { Name = reader.GetName(ordinal), Index = ordinal, Type = fieldType, }); }); T model = Activator.CreateInstance <T>(); typeof(T).GetProperties().ToList().ForEach(prop => { var column = columnList.FirstOrDefault(obj => obj.Type == prop.PropertyType && string.Equals(prop.Name, obj.Name, StringComparison.CurrentCultureIgnoreCase)); if (column == null) { prop.SetValue(model, TypeHelper.GetDefault(prop.PropertyType), null); } else { prop.SetValue(model, FieldReader.GetReaderMethod(prop.PropertyType).Invoke(dbReader, new object[] { column.Index }), null); } }); return(model); }
/// <summary> /// 使用表达式 /// </summary> /// <param name="reader"></param> /// <returns></returns> public static Func <IDataReader, T> Deserialize(IDataReader reader) { ParameterExpression readerParam = Expression.Parameter(typeof(FieldReader), "reader"); ParameterExpression outerReaderParam = Expression.Parameter(typeof(IDataReader), "outerReader"); var columnList = Enumerable.Range(0, reader.FieldCount).Select(ordinal => { Type fieldType = reader.GetFieldType(ordinal); return(new ColumnInfo { Type = fieldType, Name = reader.GetName(ordinal), Index = ordinal, Reader = Expression.Call(readerParam, FieldReader.GetReaderMethod(fieldType), new Expression[] { Expression.Constant(ordinal) }) }); }); var propList = typeof(T).GetProperties().Select(prop => { var column = columnList.FirstOrDefault(obj => obj.Type == prop.PropertyType && string.Equals(prop.Name, obj.Name, StringComparison.CurrentCultureIgnoreCase)); if (column == null) { return(new TPropertyInfo { Info = prop, Expression = Expression.Call(readerParam, typeof(FieldReader).GetMethod("GetDefault"), new[] { Expression.Constant(prop.PropertyType) }) }); } return(new TPropertyInfo { Info = prop, Expression = column.Reader }); }); ConstructorInfo[] constructorList = typeof(T).GetConstructors(); Expression lambdaBody; if (constructorList.Any(ctor => ctor.GetParameters().Count() == 0)) { lambdaBody = Expression.MemberInit(Expression.New(typeof(T)), propList.Select(obj => Expression.Bind(obj.Info as MemberInfo, obj.Expression) as MemberBinding)); } else { ConstructorInfo constructor = constructorList.FirstOrDefault(obj => obj.GetParameters().Count() == propList.Count()); if (constructor == null) { throw new ArgumentException(" 该类型构造函数参数个数与属性不匹配"); } lambdaBody = Expression.New(constructor, propList.Select(obj => obj.Expression)); } Expression <Func <IDataReader, FieldReader> > CreateDbFieldReader = (_reader) => new DbFieldReader(_reader); LambdaExpression innerLambda = Expression.Lambda <Func <FieldReader, T> >(lambdaBody, readerParam); Expression fieldReader = Expression.Invoke(CreateDbFieldReader, outerReaderParam); return(Expression.Lambda <Func <IDataReader, T> >(Expression.Invoke(innerLambda, fieldReader), outerReaderParam).Compile()); }
public static Func <IDataReader, T> ILDeserialize(IDataReader reader) { var columnList = Enumerable.Range(0, reader.FieldCount).Select(ordinal => { Type fieldType = reader.GetFieldType(ordinal); return(new { Type = fieldType, Name = reader.GetName(ordinal), Index = ordinal, Reader = FieldReader.GetReaderMethod(fieldType) }); }); Type targetType = typeof(T); var dm = new DynamicMethod(string.Format("Deserialize_{0}", Guid.NewGuid()), targetType, new[] { typeof(IDataReader) }, true); var il = dm.GetILGenerator(); il.DeclareLocal(targetType); ConstructorInfo specializedConstructor = null; if (targetType.IsValueType) { il.Emit(OpCodes.Ldloca_S, (byte)0); il.Emit(OpCodes.Initobj, targetType); } else { //构造函数集合 var constructors = targetType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).OrderBy(c => c.IsPublic ? 0 : (c.IsPrivate ? 2 : 1)).ThenBy(c => c.GetParameters().Length); ConstructorInfo defaultContructor = constructors.FirstOrDefault(c => c.GetParameters().Count() == 0); if (defaultContructor != null) { il.Emit(OpCodes.Newobj, defaultContructor); il.Emit(OpCodes.Stloc_0); if (typeof(ISupportInitialize).IsAssignableFrom(targetType)) { il.Emit(OpCodes.Ldloc_0); il.EmitCall(OpCodes.Callvirt, typeof(ISupportInitialize).GetMethod("BeginInit"), null); } } else { specializedConstructor = constructors.First(); } if (targetType.IsValueType) { il.Emit(OpCodes.Ldloca_S, (byte)0); } else if (specializedConstructor == null) { il.Emit(OpCodes.Ldloc_0); } typeof(T).GetProperties().Select(prop => { return(new { Info = prop, Setter = GetPropertySetter(prop, prop.PropertyType) }); }).ToList() .ForEach(tmp => { int valueIndex = il.DeclareLocal(tmp.Info.PropertyType).LocalIndex; var column = columnList.FirstOrDefault(obj => obj.Type == tmp.Info.PropertyType && string.Equals(tmp.Info.Name, obj.Name, StringComparison.CurrentCultureIgnoreCase)); if (column == null || tmp.Setter == null) { if (tmp.Info.PropertyType.IsValueType) { LoadLocalAddress(il, valueIndex); il.Emit(OpCodes.Initobj, tmp.Info.PropertyType); StoreLocal(il, valueIndex); LoadLocal(il, valueIndex); } else { il.Emit(OpCodes.Ldnull); } } else { il.Emit(OpCodes.Dup); il.Emit(OpCodes.Callvirt, column.Reader); //StoreLocal(il, valueIndex); il.Emit(OpCodes.Callvirt, tmp.Setter); } }); if (specializedConstructor != null) { il.Emit(OpCodes.Newobj, specializedConstructor); } if (typeof(ISupportInitialize).IsAssignableFrom(targetType)) { il.EmitCall(OpCodes.Callvirt, typeof(ISupportInitialize).GetMethod("EndInit"), null); } } il.Emit(OpCodes.Pop); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ret); return((Func <IDataReader, T>)dm.CreateDelegate(typeof(Func <IDataReader, T>))); }