// 获取 LEFT JOIN / INNER JOIN 子句关联表的的别名 private void GetLfInJoinAlias(DbExpression exp, TableAliasCache aliases) { Type type = exp.Expressions[0].Type.GetGenericArguments()[0]; string name = TypeRuntimeInfoCache.GetRuntimeInfo(type).TableName; // on a.Name equals b.Name 或 on new{ Name = a.Name,Id=a.Id } equals new { Name = b.Name,Id=b.Id } LambdaExpression left = exp.Expressions[1] as LambdaExpression; LambdaExpression right = exp.Expressions[2] as LambdaExpression; NewExpression body1 = left.Body as NewExpression; if (body1 == null) { aliases.GetTableAlias(exp.Expressions[1]); string alias = aliases.GetTableAlias(exp.Expressions[2]); // 记录显示指定的LEFT JOIN 表别名 aliases.AddOrUpdateJoinTableAlias(name, alias); } else { NewExpression body2 = right.Body as NewExpression; for (int index = 0; index < body1.Arguments.Count; ++index) { aliases.GetTableAlias(body1.Arguments[index]); string alias = aliases.GetTableAlias(body2.Arguments[index]); // 记录显示指定的LEFT JOIN 表别名 aliases.AddOrUpdateJoinTableAlias(name, alias); } } }
/// <summary> /// 追加列名 /// </summary> /// <param name="aliases">表别名</param> /// <param name="expression">列名表达式</param> /// <returns>返回解析到的表别名</returns> public string AppendMember(TableAliasCache aliases, Expression expression) { Expression exp = expression; LambdaExpression lambdaExpression = exp as LambdaExpression; if (lambdaExpression != null) { exp = lambdaExpression.Body; } MemberExpression memExp = exp as MemberExpression; if (expression.NodeType == ExpressionType.Constant || memExp.Expression.NodeType == ExpressionType.Constant) { PartialVisitor visitor = new PartialVisitor(); var eval = visitor.Eval(memExp ?? expression); string value = eval.NodeType == ExpressionType.Constant ? ExpressionVisitorBase.GetSqlValue((eval as ConstantExpression).Value) : string.Empty; _builder.Append(value); return(value); } else { string alias = aliases == null ? null : aliases.GetTableAlias(memExp); this.AppendMember(alias, memExp.Member.Name); return(alias); } }
/// <summary> /// 初始化 <see cref="OrderByExpressionVisitor"/> 类的新实例 /// </summary> public OrderByExpressionVisitor(DbQueryProviderBase provider, TableAliasCache aliases, List <DbExpression> qOrder, DbExpression groupBy = null, string alias = null) : base(provider, aliases, null, false) { _qOrder = qOrder; _aliases = aliases; _groupBy = groupBy; _alias = alias; }
// 获取 CROSS JOIN 子句关联表的的别名 private void GetCrossJoinAlias(DbExpression exp, TableAliasCache aliases) { LambdaExpression lambdaExp = exp.Expressions[1] as LambdaExpression; for (int index = 0; index < lambdaExp.Parameters.Count; ++index) { aliases.GetTableAlias(lambdaExp.Parameters[index]); } }
/// <summary> /// 初始化 <see cref="StatisExpressionVisitor"/> 类的新实例 /// </summary> public StatisExpressionVisitor(DbQueryProviderBase provider, TableAliasCache aliases, DbExpression statis, DbExpression groupBy = null, string alias = null) : base(provider, aliases, statis.Expressions != null ? statis.Expressions[0] : null, false) { _provider = provider; _aliases = aliases; _statis = statis; _groupBy = groupBy; _alias = alias; }
/// <summary> /// 初始化 <see cref="ExpressionVisitorBase"/> 类的新实例 /// </summary> public ExpressionVisitorBase(DbQueryProviderBase provider, TableAliasCache aliases, Expression exp, bool useNominate = true) { _provider = provider; _aliases = aliases; _navigations = new Dictionary <string, MemberExpression>(); _expression = exp; //var visitor = new PartialVisitor(); //_expression = useNominate ? visitor.Eval(exp) : exp; }
/// <summary> /// 实例化 <see cref="Builder" /> 的新实例 /// </summary> /// <param name="escCharLeft">如 [</param> /// <param name="escCharRight">如 ]</param> /// <param name="aliases">别名</param> public Builder(char escCharLeft, char escCharRight, TableAliasCache aliases) { _escCharLeft = escCharLeft; _escCharRight = escCharRight; _aliases = aliases; _navigations = new Dictionary <string, MemberExpression>(); _joinFragment = new SqlBuilder(escCharLeft, escCharRight); _whereFragment = new SqlBuilder(escCharLeft, escCharRight); }
/// <summary> /// 初始化 <see cref="ColumnExpressionVisitor"/> 类的新实例 /// </summary> public ColumnExpressionVisitor(DbQueryProviderBase provider, TableAliasCache aliases, DbExpression exp, DbExpression groupBy = null, bool mOnly = false) : base(provider, aliases, exp.Expressions != null ? exp.Expressions[0] : null) { _provider = provider; _aliases = aliases; _groupBy = groupBy; _mOnly = mOnly; _columns = new Dictionary <string, Column>(); _navDescriptors = new ColumnNavDescriptorCollection(); _navDescriptorKeys = new List <string>(10); }
// LEFT OR INNER JOIN private void AppendLfInJoin(SqlBuilder builder, DbExpression exp, TableAliasCache aliases) { // [TableName] //var constExp = exp.Expressions[0] as ConstantExpression; //constExp.Type.GetGenericArguments()[0] //var queryable = constExp.Value as IDbQueryable; //var innerExp = queryable.DbExpressions[0]; //if (innerExp.DbExpressionType != DbExpressionType.GetTable) throw new XfwException("inner expression must be GetTable<T> expression"); //Type type = (innerExp.Expression as ConstantExpression).Value as Type; Type type = exp.Expressions[0].Type.GetGenericArguments()[0]; builder.Append(' '); builder.AppendMember(TypeRuntimeInfoCache.GetRuntimeInfo(type).TableName); LambdaExpression left = exp.Expressions[1] as LambdaExpression; LambdaExpression right = exp.Expressions[2] as LambdaExpression; NewExpression body1 = left.Body as NewExpression; NewExpression body2 = right.Body as NewExpression; // t0(t1) string alias = body1 == null ? aliases.GetTableAlias(exp.Expressions[2]) : aliases.GetTableAlias(body2.Arguments[0]); builder.Append(' '); builder.Append(alias); builder.Append(' '); // ON a.Name = b.Name AND a.Id = b.Id builder.Append("ON "); if (body1 == null) { builder.AppendMember(aliases, left.Body.ReduceUnary()); builder.Append(" = "); builder.AppendMember(aliases, right.Body.ReduceUnary()); } else { for (int index = 0; index < body1.Arguments.Count; ++index) { builder.AppendMember(aliases, body1.Arguments[index]); builder.Append(" = "); builder.AppendMember(aliases, body2.Arguments[index]); if (index < body1.Arguments.Count - 1) { builder.Append(" AND "); } } } }
// Cross Join private void AppendCrossJoin(SqlBuilder builder, DbExpression exp, TableAliasCache aliases) { LambdaExpression lambdaExp = exp.Expressions[1] as LambdaExpression; Type type = lambdaExp.Parameters[1].Type; builder.Append(' '); builder.AppendMember(TypeRuntimeInfoCache.GetRuntimeInfo(type).TableName); string alias = aliases.GetTableAlias(lambdaExp.Parameters[1]); builder.Append(' '); builder.Append(alias); builder.Append(' '); }
/// <summary> /// 根据指定表达式取表别名 /// </summary> /// <param name="exp">表达式</param> /// <remarks> /// t=>t.Id /// t.Id /// </remarks> public string GetTableAlias(Expression exp) { // p=>p.p // p=>p.Id // p=>p.t.Id // p.Id // p.t.Id // p.t // <>h__TransparentIdentifier0.p.Id XfwException.Check.NotNull(exp, "exp"); string key = TableAliasCache.GetTableAliasKey(exp); return(this.GetTableAlias(key)); }
private static string GetTableAliasKey(Expression exp) { if (exp == null) { return(null); } Expression expression = exp; //c if (exp.NodeType == ExpressionType.Constant) { return(null); } // p ParameterExpression paramExp = expression as ParameterExpression; if (paramExp != null) { return(paramExp.Name); } // a=>a.Id LambdaExpression lambdaExp = expression as LambdaExpression; if (lambdaExp != null) { expression = lambdaExp.Body.ReduceUnary(); } // a.Id // t.a // t.t.a // t.a.Id MemberExpression memExp = expression as MemberExpression; if (memExp == null) { return(TableAliasCache.GetTableAliasKey(expression)); } if (memExp.IsVisitable()) { return(TableAliasCache.GetTableAliasKey(memExp.Expression)); } return(memExp.Member.Name); }
// 获取 JOIN 子句关联表的的别名 protected TableAliasCache PrepareAlias <T>(DbQueryableInfo_Select <T> query) { TableAliasCache aliases = new TableAliasCache((query.Join != null ? query.Join.Count : 0) + 1); foreach (DbExpression exp in query.Join) { // [INNER/LEFT JOIN] if (exp.DbExpressionType == DbExpressionType.GroupJoin || exp.DbExpressionType == DbExpressionType.Join) { this.GetLfInJoinAlias(exp, aliases); } else if (exp.DbExpressionType == DbExpressionType.SelectMany) { this.GetCrossJoinAlias(exp, aliases); } } return(aliases); }
/// <summary> /// 实例化 <see cref="CommandDefine_Select"/> 类的新实例 /// </summary> /// <param name="escCharLeft">如 [</param> /// <param name="escCharRight">如 ]</param> /// <param name="aliases">别名</param> public CommandDefine_Select(char escCharLeft, char escCharRight, TableAliasCache aliases) : base(string.Empty, null, System.Data.CommandType.Text) { _builder = new Builder(escCharLeft, escCharRight, aliases); }
/// <summary> /// 初始化 <see cref="HavingExpressionVisitor"/> 类的新实例 /// </summary> public HavingExpressionVisitor(DbQueryProviderBase provider, TableAliasCache aliases, DbExpression having, DbExpression groupBy) : base(provider, aliases, having.Expressions != null ? having.Expressions[0] : null) { _groupBy = groupBy; _aliases = aliases; }
/// <summary> /// 初始化 <see cref="WhereExpressionVisitor"/> 类的新实例 /// </summary> public WhereExpressionVisitor(DbQueryProviderBase provider, TableAliasCache aliases, DbExpression exp) : base(provider, aliases, exp.Expressions != null ? exp.Expressions[0] : null) { _expression = base.Expression; }
/// <summary> /// 初始化 <see cref="GroupByExpressionVisitor"/> 类的新实例 /// </summary> public GroupByExpressionVisitor(DbQueryProviderBase provider, TableAliasCache aliases, DbExpression groupBy) : base(provider, aliases, groupBy != null ? groupBy.Expressions[0] : null, false) { }
/// <summary> /// 追加列名 /// </summary> /// <param name="expression">列名表达式</param> /// <param name="aliases">表别名</param> /// <returns>返回解析到的表别名</returns> public Expression AppendMember(Expression expression, TableAliasCache aliases) { this.AppendMember(aliases, expression); return(expression); }
/// <summary> /// 初始化 <see cref="UpdateExpressionVisitor"/> 类的新实例 /// </summary> public UpdateExpressionVisitor(DbQueryProviderBase provider, TableAliasCache aliases, Expression exp) : base(provider, aliases, exp) { _provider = provider; _aliases = aliases; }
/// <summary> /// 初始化 <see cref="JoinExpressionVisitor"/> 类的新实例 /// </summary> public JoinExpressionVisitor(DbQueryProviderBase provider, TableAliasCache aliases, List <DbExpression> qJoin) : base(provider, aliases, null, false) { _qJoin = qJoin; _aliases = aliases; }