Exemplo n.º 1
0
        public TResult Execute <TResult>(Expression expression)
        {
            var stackCallExps = new Stack <MethodCallExpression>();
            var callExp       = expression as MethodCallExpression;

            while (callExp != null)
            {
                stackCallExps.Push(callExp);
                callExp = callExp?.Arguments.FirstOrDefault() as MethodCallExpression;
            }

            SelectGroupingProvider groupBy = null;
            var isfirst = false;

            while (stackCallExps.Any())
            {
                callExp = stackCallExps.Pop();
                TResult throwCallExp(string message) => throw new Exception($"FreeSql Queryable 解析出错,执行的方法 {callExp.Method.Name} {message}");

                if (callExp.Method.DeclaringType != typeof(Queryable))
                {
                    return(throwCallExp($"必须属于 System.Linq.Queryable"));
                }

                TResult tplMaxMinAvgSum(string method)
                {
                    if (callExp.Arguments.Count == 2)
                    {
                        var avgParam = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression;
                        return((TResult)Utils.GetDataReaderValue(typeof(TResult),
                                                                 _select.GetType().GetMethod(method).MakeGenericMethod(avgParam.ReturnType).Invoke(_select, new object[] { avgParam })));
                    }
                    return(throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"));
                }

                TResult tplOrderBy(string method, bool isDescending)
                {
                    if (callExp.Arguments.Count == 2)
                    {
                        var arg1 = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression;
                        _select.OrderByReflection(arg1, isDescending);
                        return(default(TResult));
                    }
                    return(throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"));
                }

                switch (callExp.Method.Name)
                {
                case "Any":
                    if (callExp.Arguments.Count == 2)
                    {
                        _select.InternalWhere(callExp.Arguments[1]);
                    }
                    return((TResult)(object)_select.Any());

                case "AsQueryable":
                    break;

                case "Max": return(tplMaxMinAvgSum("Max"));

                case "Min": return(tplMaxMinAvgSum("Min"));

                case "Sum": return(tplMaxMinAvgSum("Sum"));

                case "Average": return(tplMaxMinAvgSum("Avg"));

                case "Concat":
                    return(throwCallExp(" 不支持"));

                case "Contains":
                    if (callExp.Arguments.Count == 2)
                    {
                        var dywhere = callExp.Arguments[1].GetConstExprValue();
                        if (dywhere == null)
                        {
                            return(throwCallExp($" 参数值不能为 null"));
                        }
                        _select.WhereDynamic(dywhere);
                        return((TResult)(object)_select.Any());
                    }
                    return(throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"));

                case "Count":
                    if (callExp.Arguments.Count == 2)
                    {
                        _select.InternalWhere(callExp.Arguments[1]);
                    }
                    return((TResult)Utils.GetDataReaderValue(typeof(TResult), _select.Count()));

                case "Distinct":
                    if (callExp.Arguments.Count == 1)
                    {
                        _select.Distinct();
                        break;
                    }
                    return(throwCallExp(" 不支持"));

                case "ElementAt":
                case "ElementAtOrDefault":
                    _select.Offset((int)callExp.Arguments[1].GetConstExprValue());
                    _select.Limit(1);
                    isfirst = true;
                    break;

                case "First":
                case "FirstOrDefault":
                case "Single":
                case "SingleOrDefault":
                    if (callExp.Arguments.Count == 2)
                    {
                        _select.InternalWhere(callExp.Arguments[1]);
                    }
                    _select.Limit(1);
                    isfirst = true;
                    break;

                case "OrderBy":
                    tplOrderBy("OrderByReflection", false);
                    break;

                case "OrderByDescending":
                    tplOrderBy("OrderByReflection", true);
                    break;

                case "ThenBy":
                    tplOrderBy("OrderByReflection", false);
                    break;

                case "ThenByDescending":
                    tplOrderBy("OrderByReflection", true);
                    break;

                case "Where":
                    var whereParam = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression;
                    if (whereParam.Parameters.Count == 1)
                    {
                        if (groupBy != null)
                        {
                            groupBy.InternalHaving(whereParam);
                        }
                        else
                        {
                            _select.InternalWhere(whereParam);
                        }
                        break;
                    }
                    return(throwCallExp(" 不支持"));

                case "Skip":
                    _select.Offset((int)callExp.Arguments[1].GetConstExprValue());
                    break;

                case "Take":
                    _select.Limit((int)callExp.Arguments[1].GetConstExprValue());
                    break;

                case "ToList":
                    if (callExp.Arguments.Count == 1)
                    {
                        return((TResult)(object)_select.ToList());
                    }
                    return(throwCallExp(" 不支持"));

                case "Select":
                    var selectParam = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression;
                    if (selectParam.Parameters.Count == 1)
                    {
                        _select._selectExpression = selectParam;
                        break;
                    }
                    return(throwCallExp(" 不支持"));

                case "Join":
                    if (callExp.Arguments.Count == 5)
                    {
                        var arg2 = (callExp.Arguments[2] as UnaryExpression)?.Operand as LambdaExpression;
                        var arg3 = (callExp.Arguments[3] as UnaryExpression)?.Operand as LambdaExpression;
                        var arg4 = (callExp.Arguments[4] as UnaryExpression)?.Operand as LambdaExpression;
                        FreeSqlExtensionsLinqSql.InternalJoin2(_select, arg2, arg3, arg4);
                        _select._selectExpression = arg4.Body;
                        break;
                    }
                    return(throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"));

                case "GroupJoin":
                    if (callExp.Arguments.Count == 5)
                    {
                        var arg2 = (callExp.Arguments[2] as UnaryExpression)?.Operand as LambdaExpression;
                        var arg3 = (callExp.Arguments[3] as UnaryExpression)?.Operand as LambdaExpression;
                        var arg4 = (callExp.Arguments[4] as UnaryExpression)?.Operand as LambdaExpression;
                        FreeSqlExtensionsLinqSql.InternalJoin2(_select, arg2, arg3, arg4);
                        _select._selectExpression = arg4.Body;
                        break;
                    }
                    return(throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"));

                case "SelectMany":
                    if (callExp.Arguments.Count == 3)
                    {
                        var arg1 = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression;
                        var arg2 = (callExp.Arguments[2] as UnaryExpression)?.Operand as LambdaExpression;
                        FreeSqlExtensionsLinqSql.InternalSelectMany2(_select, arg1, arg2);
                        _select._selectExpression = arg2.Body;
                        break;
                    }
                    return(throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"));

                case "DefaultIfEmpty":
                    break;

                case "Last":
                case "LastOrDefault":
                    return(throwCallExp(" 不支持"));

                case "GroupBy":
                    return(throwCallExp(" 不支持"));

                    if (callExp.Arguments.Count == 2)     //TODO: 待实现
                    {
                        var arg1 = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression;

                        var map   = new ReadAnonymousTypeInfo();
                        var field = new StringBuilder();
                        var index = -10000;                                                                                                                       //临时规则,不返回 as1

                        _select._commonExpression.ReadAnonymousField(_select._tables, field, map, ref index, arg1, null, _select._whereCascadeExpression, false); //不走 DTO 映射
                        var sql = field.ToString();
                        _select.GroupBy(sql.Length > 0 ? sql.Substring(2) : null);
                        groupBy = new SelectGroupingProvider(_select._orm, _select, map, sql, _select._commonExpression, _select._tables);
                        break;
                    }
                    return(throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"));

                default:
                    return(throwCallExp(" 不支持"));
                }
            }
            if (isfirst)
            {
                _select.Limit(1);
                if (_select._selectExpression != null)
                {
                    return((TResult)(object)_select.InternalToList <TCurrent>(_select._selectExpression).FirstOrDefault());
                }
                return((TResult)(object)_select.ToList().FirstOrDefault());
            }
            if (_select._selectExpression != null)
            {
                return((TResult)(object)_select.InternalToList <TCurrent>(_select._selectExpression));
            }
            return((TResult)(object)_select.ToList());
        }
Exemplo n.º 2
0
        public object ExecuteExp(Expression expression, Type tresult, bool isProcessed)
        {
            var callExp = expression as MethodCallExpression;
            var isfirst = false;

            if (callExp != null && isProcessed == false)
            {
                object throwCallExp(string message) => throw new Exception($"解析失败 {callExp.Method.Name} {message},提示:可以使用扩展方法 IQueryable.RestoreToSelect() 还原为 ISelect 再查询");

                if (callExp.Method.DeclaringType != typeof(Queryable))
                {
                    return(throwCallExp($"必须属于 System.Linq.Queryable"));
                }

                object tplMaxMinAvgSum(string method)
                {
                    if (callExp.Arguments.Count == 2)
                    {
                        var avgParam = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression;
                        return(Utils.GetDataReaderValue(tresult,
                                                        _select.GetType().GetMethod(method).MakeGenericMethod(avgParam.ReturnType).Invoke(_select, new object[] { avgParam })));
                    }
                    return(throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"));
                }

                object tplOrderBy(string method, bool isDescending)
                {
                    if (callExp.Arguments.Count == 2)
                    {
                        var arg1 = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression;
                        _select.OrderByReflection(arg1, isDescending);
                        return(tresult.CreateInstanceGetDefaultValue());
                    }
                    return(throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"));
                }

                switch (callExp.Method.Name)
                {
                case "Any":
                    if (callExp.Arguments.Count == 2)
                    {
                        _select.InternalWhere(callExp.Arguments[1]);
                    }
                    return(_select.Any());

                case "AsQueryable":
                    break;

                case "Max": return(tplMaxMinAvgSum("Max"));

                case "Min": return(tplMaxMinAvgSum("Min"));

                case "Sum": return(tplMaxMinAvgSum("Sum"));

                case "Average": return(tplMaxMinAvgSum("Avg"));

                case "Concat":
                    return(throwCallExp(" 不支持"));

                case "Contains":
                    if (callExp.Arguments.Count == 2)
                    {
                        var dywhere = callExp.Arguments[1].GetConstExprValue();
                        if (dywhere == null)
                        {
                            return(throwCallExp($" 参数值不能为 null"));
                        }
                        _select.WhereDynamic(dywhere);
                        return(_select.Any());
                    }
                    return(throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"));

                case "Count":
                    if (callExp.Arguments.Count == 2)
                    {
                        _select.InternalWhere(callExp.Arguments[1]);
                    }
                    return(Utils.GetDataReaderValue(tresult, _select.Count()));

                case "Distinct":
                    if (callExp.Arguments.Count == 1)
                    {
                        _select.Distinct();
                        break;
                    }
                    return(throwCallExp(" 不支持"));

                case "ElementAt":
                case "ElementAtOrDefault":
                    _select.Offset((int)callExp.Arguments[1].GetConstExprValue());
                    _select.Limit(1);
                    isfirst = true;
                    break;

                case "First":
                case "FirstOrDefault":
                case "Single":
                case "SingleOrDefault":
                    if (callExp.Arguments.Count == 2)
                    {
                        _select.InternalWhere(callExp.Arguments[1]);
                    }
                    _select.Limit(1);
                    isfirst = true;
                    break;

                case "OrderBy":
                    tplOrderBy("OrderByReflection", false);
                    break;

                case "OrderByDescending":
                    tplOrderBy("OrderByReflection", true);
                    break;

                case "ThenBy":
                    tplOrderBy("OrderByReflection", false);
                    break;

                case "ThenByDescending":
                    tplOrderBy("OrderByReflection", true);
                    break;

                case "Where":
                    var whereParam = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression;
                    if (whereParam.Parameters.Count == 1)
                    {
                        _select.InternalWhere(whereParam);
                        break;
                    }
                    return(throwCallExp(" 不支持"));

                case "Skip":
                    _select.Offset((int)callExp.Arguments[1].GetConstExprValue());
                    break;

                case "Take":
                    _select.Limit((int)callExp.Arguments[1].GetConstExprValue());
                    break;

                case "ToList":
                    if (callExp.Arguments.Count == 1)
                    {
                        return(_select.ToList());
                    }
                    return(throwCallExp(" 不支持"));

                case "Select":
                    var selectParam = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression;
                    if (selectParam.Parameters.Count == 1)
                    {
                        _select._selectExpression = selectParam;
                        break;
                    }
                    return(throwCallExp(" 不支持"));

                case "Join":
                    if (callExp.Arguments.Count == 5)
                    {
                        var arg2 = (callExp.Arguments[2] as UnaryExpression)?.Operand as LambdaExpression;
                        var arg3 = (callExp.Arguments[3] as UnaryExpression)?.Operand as LambdaExpression;
                        var arg4 = (callExp.Arguments[4] as UnaryExpression)?.Operand as LambdaExpression;
                        FreeSqlExtensionsLinqSql.InternalJoin2(_select, arg2, arg3, arg4);
                        _select._selectExpression = arg4.Body;
                        break;
                    }
                    return(throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"));

                case "GroupJoin":
                    if (callExp.Arguments.Count == 5)
                    {
                        var arg2 = (callExp.Arguments[2] as UnaryExpression)?.Operand as LambdaExpression;
                        var arg3 = (callExp.Arguments[3] as UnaryExpression)?.Operand as LambdaExpression;
                        var arg4 = (callExp.Arguments[4] as UnaryExpression)?.Operand as LambdaExpression;
                        FreeSqlExtensionsLinqSql.InternalJoin2(_select, arg2, arg3, arg4);
                        _select._selectExpression = arg4.Body;
                        break;
                    }
                    return(throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"));

                case "SelectMany":
                    if (callExp.Arguments.Count == 3)
                    {
                        var arg1 = (callExp.Arguments[1] as UnaryExpression)?.Operand as LambdaExpression;
                        var arg2 = (callExp.Arguments[2] as UnaryExpression)?.Operand as LambdaExpression;
                        FreeSqlExtensionsLinqSql.InternalSelectMany2(_select, arg1, arg2);
                        _select._selectExpression = arg2.Body;
                        break;
                    }
                    return(throwCallExp($" 不支持 {callExp.Arguments.Count}个参数的方法"));

                case "DefaultIfEmpty":
                    break;

                case "Last":
                case "LastOrDefault":
                    return(throwCallExp(" 不支持"));

                case "GroupBy":
                    return(throwCallExp(" 不支持"));

                default:
                    return(throwCallExp(" 不支持"));
                }
            }
            if (tresult == null)
            {
                return(null);
            }
            if (isfirst)
            {
                _select.Limit(1);
                if (_select._selectExpression != null)
                {
                    return(_select.InternalToList <TCurrent>(_select._selectExpression).FirstOrDefault());
                }
                return(_select.ToList().FirstOrDefault());
            }
            if (_select._selectExpression != null)
            {
                return(_select.InternalToList <TCurrent>(_select._selectExpression));
            }
            return(_select.ToList());
        }