示例#1
0
        public static IQueryable <T> DoSelectByNewExpression <T>(BaseSql qr, NewExpression Expr)
        {
            var ret = BaseSql.Clone <T>(qr);

            ret.SelectedFields = Expr.Arguments.Select(p => ExprCompiler.Compile(qr, p, Expr.Members[Expr.Arguments.IndexOf(p)])).ToList();
            return(ret as IQueryable <T>);
        }
示例#2
0
        public static IQueryable <T> DoSelectByMethodCallExpression <T>(BaseSql sql, MethodCallExpression expr)
        {
            var ret = BaseSql.Clone <T>(sql);

            if (expr.Method.DeclaringType == typeof(SqlFn))
            {
                if (expr.Arguments.Count == 1)
                {
                    if (ret.SelectedFields == null)
                    {
                        ret.SelectedFields = new List <TreeExpr>();
                    }
                    ret.SelectedFields.Add(new TreeExpr
                    {
                        Callee = new FuncExpr
                        {
                            Name      = expr.Method.Name,
                            Arguments = expr.Arguments.Select(p => ExprCompiler.Compile(ret, p, null)).ToList()
                        }
                    });
                    return(ret as IQueryable <T>);
                }
            }
            else if (expr.Method.DeclaringType == typeof(Enumerable))
            {
                if (expr.Method.Name == "First")
                {
                }
            }
            throw new NotImplementedException();
        }
示例#3
0
文件: sql.cs 项目: nttlong/SqlBuilder
        public Sql <T> Where(Expression <Func <T, bool> > Expr)
        {
            Sql <T> ret = BaseSql.Clone <T, T>(this);

            if (!this.IsSubQuery)
            {
                if (this.SelectedFields != null && this.SelectedFields.Count > 0)
                {
                    if (ret.SelectedFields == null)
                    {
                        ret.SelectedFields = new List <TreeExpr>();
                    }
                    ret.SelectedFields.AddRange(this.SelectedFields.Select(p => p.Clone()));
                }
                if (((BaseSql)ret).filter == null)
                {
                    ((BaseSql)ret).filter = ExprCompiler.Compile(((BaseSql)ret), Expr.Body, null);
                }
                else
                {
                    ((BaseSql)ret).filter = new TreeExpr
                    {
                        Op    = ExprCompiler.GetOp(ExpressionType.And),
                        Left  = ((BaseSql)ret).filter,
                        Right = ExprCompiler.Compile(((BaseSql)ret), Expr.Body, ((MemberExpression)Expr.Body).Member)
                    };
                }
                return(ret);
            }
            else
            {
                ret.AliasCount = this.AliasCount + 1;
                ret.Alias      = "sql" + ret.AliasCount;
                ret.MapFields.ForEach(p => {
                    if (p.TableName == null)
                    {
                        p.TableName = ret.Alias;
                    }
                });
                ret.source = new ExprDataSource
                {
                    Alias     = ret.Alias,
                    Fields    = this.SelectedFields.Select(p => p.Clone()).ToList(),
                    Schema    = this.schema,
                    Table     = this.table,
                    Source    = this.source,
                    ParamExpr = Expression.Parameter(ret.ElementType, "p")
                };
                if (this.filter != null)
                {
                    ret.source.filter = this.filter.Clone();
                }
                ret.filter = ExprCompiler.Compile(((BaseSql)ret), Expr.Body, null);
                return(ret);
            }
        }
示例#4
0
        public static IQueryable <T> DoSelectByMMemberInitExpression <T>(BaseSql qr, MemberInitExpression Expr)
        {
            var ret = BaseSql.Clone <T>(qr);

            ret.SelectedFields = new List <TreeExpr>();
            foreach (MemberAssignment mba in Expr.Bindings)
            {
                ret.SelectedFields.Add(ExprCompiler.Compile(ret, mba.Expression, mba.Member));
            }

            return(ret);
        }
示例#5
0
        internal static Sql <T> DoGroupBy <T>(MethodCallExpression expr)
        {
            var sql = Expression.Lambda(expr.Arguments[0]).Compile().DynamicInvoke() as BaseSql;
            var ret = BaseSql.Clone <T>(sql);

            ret.MapFields.AddRange(sql.MapFields.Select(p => p.Clone()));
            var ExprGroupBy = expr.Arguments[1];

            ret.GroupByFields = ExprCompiler.GetSelectedFieldsFromExpression(ret, ExprGroupBy);
            ret.IsSubQuery    = true;
            var mbxs = ExprCompiler.GetAllMemberExpression(expr);

            typeof(T).GetProperties().ToList().ForEach(p =>
            {
                ret.MapFields.Add(new MapFieldInfo
                {
                    Member    = p,
                    ParamExpr = Expression.Parameter(p.PropertyType, "p"),
                    Name      = p.Name
                });
            });
            return(ret);
        }
示例#6
0
文件: sql.cs 项目: nttlong/SqlBuilder
        public Sql <T2> Join <T1, T2>(Sql <T1> sql, Expression <Func <T, T1, bool> > ExprJoin, Expression <Func <T, T1, T2> > Selector)
        {
            if ((!this.IsSubQuery) && (!sql.IsSubQuery))
            {
                var ret = new Sql <T2>();

                ret.MapFields = new List <MapFieldInfo>();
                this.AliasCount++;
                sql.AliasCount++;
                ret.AliasCount++;
                var leftAlias  = "l" + ret.AliasCount + "" + (this.AliasCount);
                var rightAlias = "r" + ret.AliasCount + "" + (sql.AliasCount);

                this.MapFields.ForEach(p =>
                {
                    var P = p.Clone();
                    if (!ExprCompiler.IsPrimitiveType(((PropertyInfo)p.Member).PropertyType))
                    {
                        P.Name = null;
                    }
                    P.SetTableName(leftAlias);
                    P.ParamExpr = ExprJoin.Parameters[0];
                    ret.MapFields.Add(P);
                });
                sql.MapFields.ForEach(p =>
                {
                    var P = p.Clone();
                    if (!ExprCompiler.IsPrimitiveType(((PropertyInfo)p.Member).PropertyType))
                    {
                        P.Name = null;
                    }
                    P.SetTableName(rightAlias);
                    P.ParamExpr = ExprJoin.Parameters[1];
                    ret.MapFields.Add(P);
                });
                if (Selector.Body is NewExpression)
                {
                    var nx = Selector.Body as NewExpression;
                    if (nx.Members != null)
                    {
                        nx.Members.ToList().ForEach(p =>
                        {
                            var fx = nx.Arguments[nx.Members.IndexOf(p)];
                            var mp = ret.MapFields.FirstOrDefault(x => x.Member == p && x.ParamExpr == fx);
                            if (mp == null)
                            {
                                mp = ret.MapFields.FirstOrDefault(x => x.Member == p);
                            }
                            ret.MapFields.Add(new MapFieldInfo()
                            {
                                Alias     = (mp != null) ? mp.Alias : null,
                                AliasName = (mp != null) ? mp.AliasName : null,
                                ExprField = (mp != null) ? mp.ExprField.Clone() : null,
                                Member    = p as PropertyInfo,
                                Name      = (mp != null) ? mp.Name : p.Name
                            });
                        });
                    }
                }
                var JoinExpr = ExprCompiler.Compile(ret, ExprJoin.Body, null);
                JoinExpr.ClearAliasName();
                ret.source = new ExprDataSource
                {
                    JoinType   = "inner",
                    JoinExpr   = JoinExpr,
                    LeftSource = new ExprDataSource
                    {
                        Alias     = leftAlias,
                        Schema    = this.schema,
                        Table     = this.table,
                        ParamExpr = Expression.Parameter(this.ElementType, "p"),
                        Source    = (this.source != null)?this.source.Clone():null
                    },
                    RightSource = new ExprDataSource
                    {
                        Alias     = rightAlias,
                        Schema    = sql.schema,
                        Table     = sql.table,
                        ParamExpr = Expression.Parameter(sql.ElementType, "p"),
                        Source    = (sql.source != null) ? sql.source.Clone() : null
                    }
                };
                if (Selector.Body is NewExpression)
                {
                    ret.SelectedFields = ExprCompiler.GetSelectedFieldsFromNewExpression(ret, (NewExpression)Selector.Body);
                }
                else if (Selector.Body is MemberInitExpression)
                {
                    ret.SelectedFields = ExprCompiler.GetSelectedFieldsFromMemberInitExpression(ret, (MemberInitExpression)Selector.Body);
                }
                else if (Selector.Body is ParameterExpression)
                {
                    if (ret.SelectedFields == null)
                    {
                        ret.SelectedFields = new List <TreeExpr>();
                    }
                    if (Selector.Parameters[0] == Selector.Body)
                    {
                        ret.SelectedFields.Add(new TreeExpr
                        {
                            Field = new FieldExpr
                            {
                                TableName = leftAlias
                            }
                        });
                    }
                    else if (Selector.Body == Selector.Parameters[1])
                    {
                        ret.SelectedFields.Add(new TreeExpr
                        {
                            Field = new FieldExpr
                            {
                                TableName = rightAlias
                            }
                        });
                    }
                }
                else
                {
                    throw new NotSupportedException();
                }
                if (this.filter != null)
                {
                    ret.filter = this.filter.Clone();
                    ret.filter.SetTableName(leftAlias);
                }
                if (sql.filter != null)
                {
                    var rFilter = sql.filter.Clone();
                    rFilter.SetTableName(rightAlias);
                    sql.filter = new TreeExpr
                    {
                        Op    = ExprCompiler.GetOp(ExpressionType.And),
                        Left  = sql.filter,
                        Right = rFilter
                    };
                }
                ret.SelectedFields.Join(ret.MapFields, p => p.AliasName, q => q.Name, (p, q) => new { p, q })
                .ToList().ForEach(F =>
                {
                    F.q.ExprField = F.p.Clone();
                });
                return(ret);
            }
            throw new NotImplementedException();
        }
示例#7
0
文件: sql.cs 项目: nttlong/SqlBuilder
        public Sql <T2> Select <T2>(Expression <Func <T, T2> > Expr)
        {
            if (Expr.Body is NewExpression)
            {
                var ret = BaseSql.Clone <T, T2>(this);
                if (ret.MapFields == null)
                {
                    ret.MapFields = new List <MapFieldInfo>();
                }
                ret.MapFields.AddRange(this.MapFields.Select(p => p.Clone()));
                var nx = Expr.Body as NewExpression;
                foreach (var mbx in nx.Members)
                {
                    var          arg = nx.Arguments[nx.Members.IndexOf(mbx)];
                    MapFieldInfo mp  = null;
                    if (arg is MemberExpression)
                    {
                        mp = ret.MapFields.FirstOrDefault(p => p.Member == mbx && p.ParamExpr == Expr.Parameters[0]);
                        if (mp == null)
                        {
                            mp = ret.MapFields.FirstOrDefault(p => p.Member == mbx && p.ParamExpr.Type == Expr.Parameters[0].Type);
                        }
                        if (mp == null)
                        {
                            mp = ret.MapFields.FirstOrDefault(p => p.Name == mbx.Name && p.ParamExpr == Expr.Parameters[0]);
                        }
                        if (mp == null)
                        {
                            mp = ret.MapFields.FirstOrDefault(p => p.Name == mbx.Name && p.ParamExpr.Type == Expr.Parameters[0].Type);
                        }
                        if (mp != null)
                        {
                            mp.Member    = mbx as PropertyInfo;
                            mp.ParamExpr = Expr.Parameters[0];
                        }
                        else
                        {
                            ret.MapFields.Add(new MapFieldInfo
                            {
                                AliasName = mbx.Name,
                                Member    = mbx as PropertyInfo,
                                ParamExpr = Expr.Parameters[0],
                                Name      = ((MemberExpression)arg).Member.Name
                            });
                        }
                    }
                    else
                    {
                        ret.MapFields.Add(new MapFieldInfo
                        {
                            AliasName = mbx.Name,
                            Member    = mbx as PropertyInfo,
                            ParamExpr = Expr.Parameters[0],
                            Name      = mbx.Name
                        });
                    }
                }

                ret.SelectedFields = ExprCompiler.GetSelectedFieldsFromNewExpression(ret, (NewExpression)Expr.Body);

                var tempMapping = new List <MapFieldInfo>();

                nx.Members.ToList().ForEach(p =>
                {
                    var mp = ret.MapFields.FirstOrDefault(x => x.Member == p);
                    tempMapping.Add(new MapFieldInfo()
                    {
                        Alias     = (mp != null)?mp.Alias:null,
                        AliasName = (mp != null) ? mp.AliasName : null,
                        ExprField = (mp != null && mp.ExprField != null) ? mp.ExprField.Clone() : null,
                        Member    = p as PropertyInfo,
                        Name      = p.Name,
                        ParamExpr = Expr.Parameters[0],
                        Schema    = this.schema,
                        TableName = this.table
                    });
                });
                ret.MapFields = tempMapping;
                ret.SelectedFields.ForEach(p => {
                    if (p.Field != null)
                    {
                        if (p.Field.Name == p.Field.AliasName)
                        {
                            p.Field.AliasName = null;
                        }
                        else
                        {
                            //ret.IsSubQuery = true;
                        }
                    }
                    else if (p.Op != null)
                    {
                        //ret.IsSubQuery = true;
                    }
                });
                ret.SelectedFields.Join(ret.MapFields, p => p.AliasName, q => q.Name, (p, q) => new { p, q })
                .ToList().ForEach(F =>
                {
                    F.q.ExprField = F.p.Clone();
                });
                return(ret);
            }
            if (Expr.Body is MemberExpression)
            {
                var ret = BaseSql.Clone <T, T2>(this);
                var mp  = ret.MapFields.FirstOrDefault(p => p.Member == ((MemberExpression)Expr.Body).Member);
                if (ret.SelectedFields == null)
                {
                    ret.SelectedFields = new List <TreeExpr>();
                }
                ret.SelectedFields.Add(new TreeExpr
                {
                    Field = new FieldExpr
                    {
                        AliasName = mp.AliasName,
                        Name      = mp.Name,
                        Schema    = mp.Schema,
                        TableName = mp.TableName
                    }
                });
                ret.MapFields.Clear();
                ret.MapFields.Add(mp);
                return(ret);
            }
            if (Expr.Body is MemberInitExpression)
            {
                var mx  = Expr.Body as MemberInitExpression;
                var ret = BaseSql.Clone <T, T2>(this);
                ret.SelectedFields = ExprCompiler.GetSelectedFieldsFromMemberInitExpression(ret, mx);
                ret.SelectedFields.ForEach(p => {
                    if (p.Field != null)
                    {
                        if (p.Field.Name == p.Field.AliasName)
                        {
                            p.Field.AliasName = null;
                        }
                        else
                        {
                            ret.IsSubQuery = true;
                        }
                    }
                    //else if (p.Op != null)
                    //{
                    //    ret.IsSubQuery = true;
                    //}
                });
                return(ret);
            }
            if (Expr.Body is ParameterExpression)
            {
                var px  = Expr.Body as ParameterExpression;
                var ret = BaseSql.Clone <T, T2>(this);
                var mp  = ret.MapFields.FirstOrDefault(p => (p.ParamExpr != null) && p.ParamExpr.Type == px.Type);
                if (mp != null)
                {
                    if (ret.SelectedFields == null)
                    {
                        ret.SelectedFields = new List <TreeExpr>();
                    }
                    ret.SelectedFields.Add(new TreeExpr()
                    {
                        Field = new FieldExpr
                        {
                            TableName = mp.TableName
                        }
                    });
                    ret.MapFields.AddRange(px.Type.GetProperties().Select(p => new MapFieldInfo()
                    {
                        Member    = p,
                        Name      = p.Name,
                        Schema    = mp.Schema,
                        TableName = mp.TableName,
                        ParamExpr = px
                    }));
                }
                return(ret);
            }
            throw new NotImplementedException();
        }
示例#8
0
        public IQueryable <TElement> CreateQuery <TElement>(Expression Expr)
        {
            if (Expr is MethodCallExpression)
            {
                var cx = Expr as MethodCallExpression;
                if (cx.Method.Name == "SelectMany")
                {
                    return(ExprCompiler.DoSelectMany <TElement>(cx));
                }
                if (cx.Method.Name == "Select")
                {
                    var ret = ExprCompiler.DoSelectByMethodCallExpression <TElement>(cx) as BaseSql;
                    if (ret.MapFields == null)
                    {
                        ret.MapFields = new List <MapFieldInfo>();
                    }

                    var mbxs = ExprCompiler.GetAllMemberExpression(Expr);
                    foreach (var mbx in mbxs)
                    {
                        var mp = ret.MapFields.FirstOrDefault(p => p.ParamExpr == mbx.Expression && p.Member == mbx.Member);
                        if (mp == null)
                        {
                            ret.MapFields.Add(new MapFieldInfo
                            {
                                Alias     = ret.Alias,
                                AliasName = mbx.Member.Name,
                                Member    = mbx.Member as PropertyInfo,
                                ParamExpr = mbx.Expression as ParameterExpression,
                                Name      = mbx.Member.Name,
                                Schema    = ret.schema,
                                TableName = ret.table
                            });
                        }
                    }
                    typeof(TElement).GetProperties().ToList().ForEach(p =>
                    {
                        ret.MapFields.Add(new MapFieldInfo
                        {
                            Member    = p,
                            ParamExpr = Expression.Parameter(p.PropertyType, "p"),
                            Name      = p.Name
                        });
                    });
                    return(ret as IQueryable <TElement>);
                }
                if (cx.Method.Name == "Join")
                {
                    var qr1      = Expression.Lambda(cx.Arguments[0]).Compile().DynamicInvoke() as BaseSql;
                    var qr2      = Expression.Lambda(cx.Arguments[1]).Compile().DynamicInvoke() as BaseSql;
                    var leftKey  = (MemberExpression)((LambdaExpression)((UnaryExpression)cx.Arguments[2]).Operand).Body;
                    var rightKey = (MemberExpression)((LambdaExpression)((UnaryExpression)cx.Arguments[3]).Operand).Body;
                    var selector = cx.Arguments[4];
                    return(ExprCompiler.DoInnerJoin <TElement>(qr1, qr2, leftKey, rightKey, selector));
                }
                if (cx.Method.Name == "GroupBy")
                {
                    return(ExprCompiler.DoGroupBy <TElement>(cx) as IQueryable <TElement>);
                }
            }

            throw new System.NotImplementedException();
        }
示例#9
0
        public static Sql <T> DoInnerJoinByLambdaExpression <T>(BaseSql qr1, BaseSql qr2, LambdaExpression conditional, LambdaExpression selector)
        {
            var x = GetAllParamsExpr(conditional);
            //var y = GetAllParamsExpr(selector);
            var ret = new Sql <T>(true);

            ret.AliasCount++;
            var leftAlias   = "l" + ret.AliasCount + "" + qr1.AliasCount + "" + qr2.AliasCount;
            var righttAlias = "r" + ret.AliasCount + "" + qr1.AliasCount + "" + qr2.AliasCount;

            ret.MapFields = new List <MapFieldInfo>();
            if (qr1.MapFields != null)
            {
                qr1.MapFields.ForEach(p =>
                {
                    var P = p.Clone();

                    P.SetTableName(leftAlias);
                    ret.MapFields.Add(P);
                    P.ParamExpr  = selector.Parameters[0];
                    var P1       = P.Clone();
                    P1.ParamExpr = x[0];
                    ret.MapFields.Add(P1);
                });
            }
            if (qr2.MapFields != null)
            {
                qr2.MapFields.ForEach(p =>
                {
                    var P = p.Clone();
                    P.SetTableName(righttAlias);
                    ret.MapFields.Add(P);
                    P.ParamExpr  = selector.Parameters[1];
                    var P1       = P.Clone();
                    P1.ParamExpr = x[1];
                    ret.MapFields.Add(P1);
                });
            }
            var joinExor = ExprCompiler.Compile(ret, conditional, null);

            if (selector.Body is MemberInitExpression)
            {
                ret.SelectedFields = ExprCompiler.GetSelectedFieldsFromMemberInitExpression(ret, (MemberInitExpression)selector.Body);
            }
            if (selector.Body is NewExpression)
            {
                ret.SelectedFields = ExprCompiler.GetSelectedFieldsFromNewExpression(ret, (NewExpression)selector.Body);
            }
            ret.source = new ExprDataSource
            {
                JoinExpr = joinExor,
                JoinType = "left"
            };
            ret.source.LeftSource = new ExprDataSource
            {
                Schema = qr1.schema,
                Table  = qr1.table,
                Alias  = leftAlias,
                Source = (qr1.source != null) ? qr1.source.Clone() : null
            };
            ret.source.RightSource = new ExprDataSource
            {
                Schema = qr2.schema,
                Table  = qr2.table,
                Alias  = righttAlias,
                Source = (qr2.source != null) ? qr2.source.Clone() : null
            };

            if (selector.Body is NewExpression)
            {
                var nx = selector.Body as NewExpression;
                foreach (var mb in nx.Members)
                {
                    if (!(nx.Arguments[nx.Members.IndexOf(mb)] is ParameterExpression))
                    {
                        var fm = ret.SelectedFields.FirstOrDefault(p => (p.Field != null) && (p.Field.Name == mb.Name));
                        if (fm == null)
                        {
                            fm = ret.SelectedFields.FirstOrDefault(p => (p.Value != null) && (p.Value.AliasName == mb.Name));
                        }
                        ret.MapFields.Add(new MapFieldInfo()
                        {
                            Member    = mb as PropertyInfo,
                            ParamExpr = Expression.Parameter(typeof(T), "p"),
                            Name      = mb.Name,
                            Schema    = ret.schema,
                            TableName = ret.table,
                            ExprField = fm
                        });
                    }
                }
            }
            else if (selector.Body is MemberInitExpression)
            {
                var mbi = selector.Body as MemberInitExpression;
                foreach (MemberAssignment mba in mbi.Bindings)
                {
                    if (!(mba.Expression is ParameterExpression))
                    {
                        var fm = ret.SelectedFields.FirstOrDefault(p => (p.Field != null) && (p.Field.Name == mba.Member.Name));
                        if (fm == null)
                        {
                            fm = ret.SelectedFields.FirstOrDefault(p => (p.Value != null) && (p.Value.AliasName == mba.Member.Name));
                        }
                        ret.MapFields.Add(new MapFieldInfo()
                        {
                            Member    = mba.Member as PropertyInfo,
                            ParamExpr = Expression.Parameter(typeof(T), "p"),
                            Name      = mba.Member.Name,
                            Schema    = ret.schema,
                            TableName = ret.table,
                            ExprField = fm
                        });
                    }
                }
            }
            else
            {
                throw new NotImplementedException();
            }
            return(ret);
        }
示例#10
0
        public static IQueryable <T> DoInnerJoin <T>(BaseSql qr1, BaseSql qr2, MemberExpression leftKey, MemberExpression rightKey, Expression selector)
        {
            var ret       = new Sql <T>(true);
            var leftName  = "l" + ret.AliasCount + "" + qr1.AliasCount + "" + qr2.AliasCount;
            var rightName = "r" + ret.AliasCount + "" + qr1.AliasCount + "" + qr2.AliasCount;

            if (!(qr1.IsSubQuery) && (!qr2.IsSubQuery))
            {
                var leftMp  = qr1.MapFields.FirstOrDefault(p => p.Member == leftKey.Member);
                var rightMp = qr2.MapFields.FirstOrDefault(p => p.Member == rightKey.Member);
                ret.source = new ExprDataSource
                {
                    JoinType   = "inner",
                    LeftSource = new ExprDataSource
                    {
                        Alias  = leftName,
                        Schema = qr1.schema,
                        Table  = qr1.table
                    },
                    RightSource = new ExprDataSource
                    {
                        Alias  = rightName,
                        Schema = qr2.schema,
                        Table  = qr2.table
                    },
                    JoinExpr = new TreeExpr
                    {
                        Op   = ExprCompiler.GetOp(ExpressionType.Equal),
                        Left = new TreeExpr
                        {
                            Field = new FieldExpr
                            {
                                TableName = leftName,
                                Name      = leftMp.Name
                            }
                        },
                        Right = new TreeExpr
                        {
                            Field = new FieldExpr
                            {
                                TableName = rightName,
                                Name      = rightMp.Name
                            }
                        }
                    }
                };
                return(ret as IQueryable <T>);
            }
            if ((qr1.IsSubQuery) && (!qr2.IsSubQuery))
            {
                var sql1    = new BaseSql();
                var leftMp  = qr1.MapFields.FirstOrDefault(p => p.Member == leftKey.Member);
                var rightMp = qr2.MapFields.FirstOrDefault(p => p.Member == rightKey.Member);
                ret.source = new ExprDataSource
                {
                    JoinType   = "inner",
                    LeftSource = new ExprDataSource
                    {
                        Source = new ExprDataSource
                        {
                            Alias        = qr1.Alias,
                            Fields       = (qr1.SelectedFields != null)?qr1.SelectedFields.Select(p => p.Clone()).ToList():null,
                            filter       = (qr1.filter != null)?qr1.filter.Clone():null,
                            GroupFields  = (qr1.GroupByFields != null)?qr1.GroupByFields.Select(p => p.Clone()).ToList():null,
                            HavingFields = (qr1.HavingFields != null)?qr1.HavingFields.Select(p => p.Clone()).ToList():null,
                            Schema       = qr1.schema,
                            Table        = qr1.table,
                            JoinExpr     = (qr1.source != null)?qr1.source.JoinExpr:null,
                            JoinType     = (qr1.source != null) ? qr1.source.JoinType : null,
                            LeftSource   = (qr1.source != null) ? qr1.source.LeftSource : null,
                            RightSource  = (qr1.source != null) ? qr1.source.RightSource : null,
                            ParamExpr    = qr1.ParamExpr
                        }
                    },
                    RightSource = new ExprDataSource
                    {
                        Alias  = rightName,
                        Schema = qr2.schema,
                        Table  = qr2.table
                    },
                    JoinExpr = new TreeExpr
                    {
                        Op   = ExprCompiler.GetOp(ExpressionType.Equal),
                        Left = new TreeExpr
                        {
                            Field = new FieldExpr
                            {
                                TableName = leftName,
                                Name      = leftMp.Name
                            }
                        },
                        Right = new TreeExpr
                        {
                            Field = new FieldExpr
                            {
                                TableName = rightName,
                                Name      = rightMp.Name
                            }
                        }
                    }
                };
                if (ret.source.LeftSource.Fields == null ||
                    ret.source.Fields.Count == 0)
                {
                    ret.source.Fields = new List <TreeExpr>();
                    ret.source.Fields.Add(new TreeExpr
                    {
                        Field = new FieldExpr
                        {
                            TableName = qr1.table
                        }
                    });
                }
                return(ret as IQueryable <T>);
            }
            throw new NotSupportedException();
        }