コード例 #1
0
        /// <summary>
        /// 按Lambda创建对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="mapping"></param>
        /// <returns></returns>
        public static Func <DataContainer, T> CreateObjectGeneratorLambda <T>(IEnumerable <Attribute.FieldMapping> mapping)
        {
            var objectType     = typeof(T);
            var fields         = TypeCache.GetProperties(objectType, true);
            var parame         = Expression.Parameter(typeof(DataContainer), "par");
            var memberBindings = new List <MemberBinding>();
            //按顺序生成Binding
            int i = 0;

            foreach (var mp in mapping)
            {
                if (!fields.ContainsKey(mp.MappingName))
                {
                    continue;
                }
                var m      = fields[mp.MappingName].GetPropertyInfo();
                var method = DataContainer.GetMethod(m.PropertyType);
                //Expression getValue = Expression.Call(method, parame);
                var getValue = parame.Call(method.Name, Expression.Constant(i));
                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 <DataContainer, T> >(expr, parame);

            return(ret.Compile());
        }
コード例 #2
0
ファイル: QueryInfo.cs プロジェクト: zyj0021/CRL5
        ///// <summary>
        ///// 按Lambda创建对象
        ///// </summary>
        ///// <typeparam name="T"></typeparam>
        ///// <param name="mapping"></param>
        ///// <returns></returns>
        //static Func<DataContainer, T> CreateObjectGeneratorLambda<T>(IEnumerable<Attribute.FieldMapping> mapping)
        //{
        //    var objectType = typeof(T);
        //    var fields = TypeCache.GetProperties(objectType, true);
        //    var parame = Expression.Parameter(typeof(DataContainer), "par");
        //    var memberBindings = new List<MemberBinding>();
        //    //按顺序生成Binding
        //    int i = 0;
        //    foreach (var mp in mapping)
        //    {
        //        if (!fields.ContainsKey(mp.MemberName))
        //        {
        //            continue;
        //        }
        //        var m = fields[mp.MemberName].GetPropertyInfo();
        //        var method = DataContainer.GetMethod(m.PropertyType, true);
        //        //Expression getValue = Expression.Call(method, parame);
        //        var getValue = parame.Call(method.Name, Expression.Constant(i));
        //        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<DataContainer, T>>(expr, parame);
        //    return ret.Compile();
        //}

        /// <summary>
        /// 使用EMIT
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="mapping"></param>
        /// <param name="queryFields"></param>
        /// <returns></returns>
        public static Func <DataContainer, T> CreateObjectGeneratorEmit <T>(IEnumerable <Attribute.FieldMapping> mapping, Dictionary <string, ColumnType> queryFields)
        {
            var           type   = typeof(T);
            var           fields = TypeCache.GetProperties(type, true);
            DynamicMethod method = new DynamicMethod("CreateObjectGeneratorEmit", type,
                                                     new Type[] { typeof(CRL.LambdaQuery.Mapping.DataContainer) }, type, true);
            ILGenerator  generator = method.GetILGenerator();
            LocalBuilder result    = generator.DeclareLocal(type);

            generator.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes));
            generator.Emit(OpCodes.Stloc, result);
            //int i = 0;
            //mapping顺序和语句查询不一致
            foreach (var mp in mapping)
            {
                if (string.IsNullOrEmpty(mp.ResultName))
                {
                    throw new CRLException("ResultName为空,请检查mapping创建" + mp);
                }
                if (!queryFields.ContainsKey(mp.ResultName.ToLower()))
                {
                    continue;
                }
                if (!fields.ContainsKey(mp.ResultName))
                {
                    continue;
                }
                var i          = queryFields[mp.ResultName.ToLower()].index;
                var pro        = fields[mp.ResultName].GetPropertyInfo();
                var endIfLabel = generator.DefineLabel();
                generator.Emit(OpCodes.Ldloc, result);
                generator.Emit(OpCodes.Ldarg_0);
                generator.Emit(OpCodes.Ldc_I4, i);
                var method2 = DataContainer.GetMethod(pro.PropertyType);
                if (method2 == null)
                {
                    throw new CRLException($"找不到对应类型的解析方法{pro.Name} {pro.PropertyType} ");
                }
                generator.Emit(OpCodes.Call, method2);
                generator.Emit(OpCodes.Callvirt, pro.GetSetMethod());
                generator.MarkLabel(endIfLabel);
                //i += 1;
            }
            generator.Emit(OpCodes.Ldloc, result);
            generator.Emit(OpCodes.Ret);
            var handler = (Func <DataContainer, T>)method.CreateDelegate(typeof(Func <DataContainer, T>));

            return(handler);
        }
コード例 #3
0
        /// <summary>
        /// 使用lambda匿名对象创建
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="constructor"></param>
        /// <returns></returns>
        static Func <DataContainer, T> CreateObjectGenerator <T>(ConstructorInfo constructor)
        {
            var parame = Expression.Parameter(typeof(DataContainer), "par");

            ParameterInfo[]   parameters = constructor.GetParameters();
            List <Expression> arguments  = new List <Expression>(parameters.Length);
            int i = 0;

            foreach (var parameter in parameters)
            {
                var method   = DataContainer.GetMethod(parameter.ParameterType);
                var getValue = parame.Call(method.Name, Expression.Constant(i));
                //var getValue = Expression.Call(method, parame, Expression.Constant(i));
                arguments.Add(getValue);
                i += 1;
            }
            var body = Expression.New(constructor, arguments);
            var ret  = Expression.Lambda <Func <DataContainer, T> >(body, parame).Compile();

            return(ret);
        }