Exemplo n.º 1
0
        private static MethodInfo GetSqlMapperQueryMethod(MappingFunctionDescriptor funcDescriptor)
        {
            MethodInfo firstOrDefault =
                typeof(SqlMapper).GetMethods()
                .FirstOrDefault(
                    m =>
                    m.Name == "Query" && m.IsGenericMethod &&
                    m.GetGenericArguments().Length == funcDescriptor.GenericTypes.Length);

            if (firstOrDefault != null)
            {
                return(firstOrDefault.MakeGenericMethod(funcDescriptor.GenericTypes));
            }
            return(null);
        }
Exemplo n.º 2
0
        BuildFunction <TReturn, TFunc>()
        {
            var        mappingDescriptor    = new MappingFunctionDescriptor(typeof(TFunc));
            MethodInfo queryMethodSignature = GetSqlMapperQueryMethod(mappingDescriptor);

            // variables that are visible in main scope
            var variables = new List <ParameterExpression>();
            //body of main query method
            var methodBodyExpressions = new List <Expression>();
            ////query method incoming parameters
            //var queryMethodParameters = new List<ParameterExpression>();
            // parameters for fake map function
            var mappingParameters = new List <ParameterExpression>();
            // body for fake map function
            var mappingBodyExpressions = new List <Expression>();

            // declare and assign dictionaries and id evaluators for mapped types
            foreach (Type type in mappingDescriptor.GenericTypes.Take(mappingDescriptor.GenericTypes.Length - 1))
            {
                IStructureMap mapper = LeanMapper.GetMapper(type);
                mappingParameters.Add(Expression.Parameter(type));
                if (mapper == null)
                {
                    continue;
                }
                SetupIdDataChecker(variables, methodBodyExpressions, mappingParameters.Last(), mappingBodyExpressions,
                                   mapper);
            }

            // declare parameters for main query method (they will be passed down to inner SqlMapper.Query method call)
            ParameterExpression cnnP            = Expression.Parameter(typeof(IDbConnection), "cnn");
            ParameterExpression sqlP            = Expression.Parameter(typeof(string), "sql");
            ParameterExpression mapParam        = Expression.Parameter(mappingDescriptor.MappingType, "map");
            ParameterExpression paramP          = Expression.Parameter(typeof(object), "param");
            ParameterExpression transactionP    = Expression.Parameter(typeof(IDbTransaction), "transaction");
            ParameterExpression bufferedP       = Expression.Parameter(typeof(bool), "buffered");
            ParameterExpression splitOnP        = Expression.Parameter(typeof(string), "splitOn");
            ParameterExpression commandTimeoutP = Expression.Parameter(typeof(int?), "commandTimeout");
            ParameterExpression commandTypeP    = Expression.Parameter(typeof(CommandType?), "commandType");
            ParameterExpression newMapper       = Expression.Parameter(mappingDescriptor.MappingType, "newMapper");

            methodBodyExpressions.Add(Expression.Assign(newMapper,
                                                        FinishFakeMappingFunction <TReturn, TFunc>(mapParam, mappingParameters, mappingBodyExpressions)));
            variables.Add(newMapper);
            //call REAL Query Method
            MethodCallExpression callRealDapperMethod = Expression.Call(queryMethodSignature, cnnP, sqlP, newMapper,
                                                                        paramP, transactionP, bufferedP, splitOnP, commandTimeoutP, commandTypeP);

            LabelTarget     returnFinalTarget      = Expression.Label(typeof(IEnumerable <TReturn>));
            GotoExpression  returnFinalValue       = Expression.Return(returnFinalTarget, callRealDapperMethod);
            LabelExpression rerturnFinalExpression = Expression.Label(returnFinalTarget,
                                                                      Expression.Default(typeof(IEnumerable <TReturn>)));

            methodBodyExpressions.Add(returnFinalValue);
            methodBodyExpressions.Add(rerturnFinalExpression);

            return
                (Expression
                 .Lambda
                 <Func <IDbConnection, string, TFunc, dynamic, IDbTransaction, bool, string, int?, CommandType?,
                        IEnumerable <TReturn> > >(
                     Expression.Block(variables, methodBodyExpressions),
                     cnnP, sqlP, mapParam, paramP, transactionP, bufferedP, splitOnP, commandTimeoutP,
                     commandTypeP).Compile());
        }