예제 #1
0
        public string GetCommandText(Expression expression)
        {
            var parser = new QueryExpressionParser(_connection);

            parser.Parse(expression);
            return(parser.ToSql());
        }
예제 #2
0
        public TResult Execute <TResult>(Expression expression)
        {
            var parser = new QueryExpressionParser(_connection);

            parser.Parse(expression);

            Type type = typeof(TResult);

            if (expression.NodeType == ExpressionType.Call && type.IsValueType)
            {
                var callMethod = ((MethodCallExpression)expression).Method;
                switch (callMethod.Name)
                {
                case "Any":
                //case "Average":
                //case "Sum":
                case "Count":
                    var returnMethod = typeof(SqlMapper).GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).FirstOrDefault(x => x.Name == "ExecuteScalar" && x.IsGenericMethodDefinition).MakeGenericMethod(type);
                    var param0       = Expression.Parameter(typeof(IDbConnection));
                    var param1       = Expression.Parameter(typeof(string));
                    var param2       = Expression.Parameter(typeof(object));
                    var param3       = Expression.Parameter(typeof(IDbTransaction));
                    var param4       = Expression.Parameter(typeof(int?));
                    var param5       = Expression.Parameter(typeof(CommandType?));
                    var source       = Expression.Call(returnMethod, param0, param1, param2, param3, param4, param5);
                    return(Expression.Lambda <Func <IDbConnection, string, object, IDbTransaction, int?, CommandType?, TResult> >(source, param0, param1, param2, param3, param4, param5).Compile()(_connection, parser.ToSql(), parser.Parameters, null, null, null));

                default:
                    throw new Exception("not supported yet");
                }
            }
            else
            {
                MethodInfo method;
                //var isAnonymous = false;
                //if (!isAnonymous)
                //{
                method = typeof(SqlMapper).GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).FirstOrDefault(x => x.Name == "Query" && x.IsGenericMethodDefinition).MakeGenericMethod(type.IsGenericType ? type.GetGenericArguments() : new[] { type });
                //}
                //else
                //{
                //    method = typeof(SqlMapper).GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).FirstOrDefault(x => x.Name == "Query" && !x.IsGenericMethodDefinition);
                //}
                var param0 = Expression.Parameter(typeof(IDbConnection));
                var param1 = Expression.Parameter(typeof(string));
                var param2 = Expression.Parameter(typeof(object));
                var param3 = Expression.Parameter(typeof(IDbTransaction));
                var param4 = Expression.Parameter(typeof(bool));
                var param5 = Expression.Parameter(typeof(int?));
                var param6 = Expression.Parameter(typeof(CommandType?));
                var source = Expression.Call(method, param0, param1, param2, param3, param4, param5, param6);

                if (type.IsGenericType)
                {
                    return(Expression.Lambda <Func <IDbConnection, string, object, IDbTransaction, bool, int?, CommandType?, TResult> >(source, param0, param1, param2, param3, param4, param5, param6).Compile()(_connection, parser.ToSql(), parser.Parameters, null, true, null, null));
                }
                else
                {
                    var results    = Expression.Lambda <Func <IDbConnection, string, object, IDbTransaction, bool, int?, CommandType?, IEnumerable <TResult> > >(source, param0, param1, param2, param3, param4, param5, param6).Compile()(_connection, parser.ToSql(), parser.Parameters, null, true, null, null);
                    var callMethod = ((MethodCallExpression)expression).Method;
                    switch (callMethod.Name)
                    {
                    case "First":
                        return(results.First());

                    case "FirstOrDefault":
                        return(results.FirstOrDefault());

                    case "Last":
                        return(results.Last());

                    case "LastOrDefault":
                        return(results.LastOrDefault());

                    default:
                        throw new Exception("not supported yet");
                    }
                }
            }
        }