static Func <ObjContainer, T> CreateObjectGeneratorFromMapping <T>(IEnumerable <Attribute.FieldMapping> mapping) { var objectType = typeof(T); var fields = TypeCache.GetProperties(objectType, true); var parame = Expression.Parameter(typeof(ObjContainer), "par"); var memberBindings = new List <MemberBinding>(); //按顺序生成Binding //int i = 0; foreach (var mp in mapping) { if (!fields.ContainsKey(mp.FieldName)) { continue; } var m = fields[mp.FieldName].GetPropertyInfo(); var method = ObjContainer.GetMethod(m.PropertyType, true); //Expression getValue = Expression.Call(method, parame); var getValue = parame.Call(method.Name, Expression.Constant(mp.ResultName)); if (m.PropertyType.IsEnum) { getValue = Expression.Convert(getValue, m.PropertyType); } var bind = (MemberBinding)Expression.Bind(m, getValue); memberBindings.Add(bind); //i += 1; } Expression expr = Expression.MemberInit(Expression.New(objectType), memberBindings); var ret = Expression.Lambda <Func <ObjContainer, T> >(expr, parame); return(ret.Compile()); }
List <TResult> QueryResultNewExpression <TModel, TResult>(LambdaQuery <TModel> query, NewExpression newExpression) where TModel : IModel, new() { //query.Select(newExpression); var result = GetDynamicResult(query); var list = new List <TResult>(); Func <ObjContainer, TResult> objCreater; var parameters = newExpression.Constructor.GetParameters(); //当匿名类型指定了类型,没有构造参数 if (parameters.Length > 0) { objCreater = CreateObjectGenerator <TResult>(newExpression.Constructor); } else { objCreater = CreateObjectGeneratorFromMapping <TResult>(query.GetFieldMapping()); } foreach (IDictionary <string, object> item in result) { var objC = new ObjContainer(item); var obj = objCreater(objC); list.Add(obj); } return(list); }
static Func <ObjContainer, T> CreateObjectGenerator <T>(ConstructorInfo constructor) { var type = typeof(ObjContainer); var parame = Expression.Parameter(type, "par"); var parameters = constructor.GetParameters(); List <Expression> arguments = new List <Expression>(parameters.Length); foreach (var parameter in parameters) { var method = ObjContainer.GetMethod(parameter.ParameterType, true); var getValue = Expression.Call(parame, method, Expression.Constant(parameter.Name)); arguments.Add(getValue); } var body = Expression.New(constructor, arguments); var ret = Expression.Lambda <Func <ObjContainer, T> >(body, parame).Compile(); return(ret); }