/// <summary> /// 初始化 <see cref="NpgUpdateExpressionVisitor"/> 类的新实例 /// </summary> /// <param name="ag">表别名解析器</param> /// <param name="builder">SQL 语句生成器</param> public NpgUpdateExpressionVisitor(AliasGenerator ag, ISqlBuilder builder) : base(ag, builder) { _ag = ag; _builder = builder; _visitedStack = base.VisitedStack; }
/// <summary> /// 初始化 <see cref="OrderByExpressionVisitor"/> 类的新实例 /// </summary> /// <param name="ag">表别名解析器</param> /// <param name="builder">SQL 语句生成器</param> /// <param name="groupBy">GROUP BY 子句</param> /// <param name="alias">指定的表别名</param> public OrderByExpressionVisitor(AliasGenerator ag, ISqlBuilder builder, DbExpression groupBy, string alias) : base(ag, builder) { _ag = ag; _alias = alias; _builder = builder; _groupBy = groupBy; }
/// <summary> /// 初始化 <see cref="SQLiteUpdateExpressionVisitor"/> 类的新实例 /// </summary> /// <param name="ag">表别名解析器</param> /// <param name="builder">SQL 语句生成器</param> /// <param name="tree">更新语义</param> /// <param name="alias">指定的表达式别名</param> internal SQLiteUpdateExpressionVisitor(AliasGenerator ag, ISqlBuilder builder, DbQueryUpdateTree tree, string alias) : base(ag, builder) { _tree = tree; _alias = alias; _builder = builder; _visitedStack = base.VisitedStack; }
/// <summary> /// 初始化 <see cref="WhereExpressionVisitor"/> 类的新实例 /// </summary> /// <param name="ag">表别名解析器</param> /// <param name="builder">SQL 语句生成器</param> public WhereExpressionVisitor(AliasGenerator ag, ISqlBuilder builder) : base(ag, builder) { _builder = builder; _provider = _builder.Provider; _constor = ((DbQueryProvider)_provider).Constor; _context = _builder.TranslateContext; }
private static string GetTableAliasKey(Expression node) { if (node == null) { return(null); } //System.Console.WriteLine(exp); Expression exp = node.ReduceUnary(); // 常量表达式 c if (exp.CanEvaluate()) { return(null); } // p var parameterExpression = exp as ParameterExpression; if (parameterExpression != null) { return(parameterExpression.Name); } // a=>a.Id var lambdaExpression = exp as LambdaExpression; if (lambdaExpression != null) { if (lambdaExpression.Parameters != null && lambdaExpression.Parameters.Count == 1 && !ExpressionExtensions.IsAnonymous(lambdaExpression.Parameters[0])) { return(AliasGenerator.GetTableAliasKey(lambdaExpression.Parameters[0])); } else { exp = lambdaExpression.Body.ReduceUnary(); } } // a.Id // t.a // t.t.a // t.a.Id var memberExpression = exp as MemberExpression; if (memberExpression == null) { return(AliasGenerator.GetTableAliasKey(exp)); } if (memberExpression.Visitable()) { return(AliasGenerator.GetTableAliasKey(memberExpression.Expression)); } return(memberExpression.Member.Name); }
// 获取 CROSS JOIN 子句关联表的的别名 private void PrepareCrossAlias(DbExpression dbExpression, AliasGenerator ag) { var lambda = dbExpression.Expressions[1] as LambdaExpression; for (int index = 0; index < lambda.Parameters.Count; ++index) { ag.GetTableAlias(lambda.Parameters[index]); } }
/// <summary> /// 实例化 <see cref="SqlServerDbSelectCommand"/> 类的新实例 /// </summary> /// <param name="context">解析SQL命令上下文</param> /// <param name="ag">表别名解析器</param> /// <param name="hasMany">是否包含一对多导航属性</param> public SqlServerDbSelectCommand(ITranslateContext context, AliasGenerator ag, bool hasMany) : base(context, ag, hasMany) { _ag = ag; var dc = context.DbContext; _isNoLock = ((SqlServerDbContext)dc).NoLock; _withNoLock = ((SqlServerDbQueryProvider)dc.Provider).WidthNoLock; }
/// <summary> /// 初始化 <see cref="ColumnExpressionVisitor"/> 类的新实例 /// </summary> /// <param name="ag">表别名解析器</param> /// <param name="builder">SQL 语句生成器</param> /// <param name="tree">查询语义</param> public ColumnExpressionVisitor(AliasGenerator ag, ISqlBuilder builder, DbQuerySelectTree tree) : base(ag, builder) { _ag = ag; _builder = builder; _groupBy = tree.GroupBy; _includes = tree.Includes; _selectedColumns = new ColumnDescriptorCollection(); _visitedStack = base.VisitedStack; }
/// <summary> /// 初始化 <see cref="SqlServerJoinExpressionVisitor"/> 类的新实例 /// </summary> /// <param name="ag">表别名解析器</param> /// <param name="builder">SQL 语句生成器</param> public SqlServerJoinExpressionVisitor(AliasGenerator ag, ISqlBuilder builder) : base(ag, builder) { _ag = ag; _builder = builder; var context = builder.TranslateContext.DbContext; _isNoLock = ((SqlServerDbContext)context).NoLock; _withNoLock = ((SqlServerDbQueryProvider)context.Provider).WidthNoLock; }
/// <summary> /// 实例化 <see cref="DbSelectCommand"/> 类的新实例 /// </summary> /// <param name="context">解析SQL命令上下文</param> /// <param name="ag">别名</param> /// <param name="hasMany">是否包含一对多导航属性</param> public DbSelectCommand(ITranslateContext context, AliasGenerator ag, bool hasMany) : base(string.Empty, context != null ? context.Parameters : null, System.Data.CommandType.Text) { _ag = ag; _context = context; _hasMany = hasMany; var provider = (DbQueryProvider)_context.DbContext.Provider; _joinFragment = provider.CreateSqlBuilder(context); _whereFragment = provider.CreateSqlBuilder(context); }
/// <summary> /// 根据指定表达式取表别名 /// </summary> /// <param name="expression">表达式</param> /// <remarks> /// t=>t.Id /// t.Id /// </remarks> public string GetTableAlias(Expression expression) { // p=>p.p // p=>p.Id // p=>p.t.Id // p.Id // p.t.Id // p.t // <>h__TransparentIdentifier0.p.Id XFrameworkException.Check.NotNull(expression, "expression"); string key = AliasGenerator.GetTableAliasKey(expression); return(this.GetTableAlias(key)); }
/// <summary> /// 实例化 <see cref="NpgDbSelectCommand" /> 的新实例 /// </summary> /// <param name="context">解析SQL命令上下文</param> /// <param name="aliasGenerator">别名</param> /// <param name="dbExpressionType">表达式类型</param> /// <param name="hasMany">是否包含一对多导航属性</param> public NpgDbSelectCommand(ITranslateContext context, AliasGenerator aliasGenerator, DbExpressionType dbExpressionType, bool hasMany) : base(context, aliasGenerator, hasMany) { _aliasGenerator = aliasGenerator; _onPhrase = ((DbQueryProvider)context.Provider).CreateSqlBuilder(context); _dbExpressionType = dbExpressionType; if (_dbExpressionType == DbExpressionType.Delete) { _keywordName = "USING "; } else if (_dbExpressionType == DbExpressionType.Update) { _keywordName = "FROM "; } _pad = "".PadLeft(_keywordName.Length, ' '); }
/// <summary> /// 初始化 <see cref="NpgJoinExpressionVisitor"/> 类的新实例 /// </summary> /// <param name="ag">表别名解析器</param> /// <param name="builder">SQL 语句生成器</param> /// <param name="dbExpressionType">表达式类型</param> /// <param name="cmd">SQL 命令</param> public NpgJoinExpressionVisitor(AliasGenerator ag, ISqlBuilder builder, DbExpressionType dbExpressionType, NpgDbSelectCommand cmd) : base(ag, builder) { _ag = ag; _dbExpressionType = dbExpressionType; _cmd = cmd; if (_dbExpressionType == DbExpressionType.Delete) { _keywordName = "USING "; } else if (_dbExpressionType == DbExpressionType.Update) { _keywordName = "FROM "; } _pad = "".PadLeft(_keywordName.Length, ' '); }
/// <summary> /// 生成关联子句所表示的别名列表 /// </summary> /// <param name="tree">查询语义</param> /// <param name="prefix">表别名前缀</param> /// <returns></returns> protected AliasGenerator PrepareTableAlias(DbQuerySelectTree tree, string prefix) { var ag = new AliasGenerator((tree.Joins != null ? tree.Joins.Count : 0) + 1, prefix); for (int index = 0; index < (tree.Joins != null ? tree.Joins.Count : -1); index++) { DbExpression d = tree.Joins[index]; // [INNER/LEFT JOIN] if (d.DbExpressionType == DbExpressionType.LeftOuterJoin || d.DbExpressionType == DbExpressionType.Join || d.DbExpressionType == DbExpressionType.RightOuterJoin) { this.PrepareJoinAlias(d, ag); } else if (d.DbExpressionType == DbExpressionType.SelectMany) { this.PrepareCrossAlias(d, ag); } } return(ag); }
/// <summary> /// 初始化 <see cref="OracleUpdateExpressionVisitor"/> 类的新实例 /// </summary> /// <param name="ag">表别名解析器</param> /// <param name="builder">SQL 语句生成器</param> public OracleUpdateExpressionVisitor(AliasGenerator ag, ISqlBuilder builder) : base(ag, builder) { _builder = builder; }
/// <summary> /// 添加导航属性关联 /// </summary> protected override void TanslateNavMember() { if (base.NavMembers == null || base.NavMembers.Count == 0) { return; } // 如果有一对多的导航属性,肯定会产生嵌套查询。那么内层查询别名肯定是t0,所以需要清掉 if (this.HasMany) { _ag = new AliasGenerator(_ag.ReserveQty); } //开始产生LEFT JOIN 子句 ISqlBuilder builder = this.JoinFragment; foreach (var nav in base.NavMembers) { string key = nav.Key; MemberExpression m = nav.Expression; TypeRuntimeInfo typeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(m.Expression.Type); ForeignKeyAttribute attribute = typeRuntime.GetMemberAttribute <ForeignKeyAttribute>(m.Member.Name); string innerKey = string.Empty; string outerKey = key; string innerAlias = string.Empty; if (!m.Expression.Visitable()) { innerKey = m.Expression.NodeType == ExpressionType.Parameter ? (m.Expression as ParameterExpression).Name : (m.Expression as MemberExpression).Member.Name; } else { MemberExpression mLeft = null; if (m.Expression.NodeType == ExpressionType.MemberAccess) { mLeft = m.Expression as MemberExpression; } else if (m.Expression.NodeType == ExpressionType.Call) { mLeft = (m.Expression as MethodCallExpression).Object as MemberExpression; } string name = TypeRuntimeInfoCache.GetRuntimeInfo(mLeft.Type).TableFullName; innerAlias = _ag.GetJoinTableAlias(name); if (string.IsNullOrEmpty(innerAlias)) { string keyLeft = mLeft.GetKeyWidthoutAnonymous(); if (base.NavMembers.Contains(keyLeft)) { innerKey = keyLeft; } innerAlias = _ag.GetNavTableAlias(innerKey); } } string alias1 = !string.IsNullOrEmpty(innerAlias) ? innerAlias : _ag.GetTableAlias(innerKey); string alias2 = _ag.GetNavTableAlias(outerKey); builder.AppendNewLine(); builder.Append("LEFT JOIN "); Type type = m.Type; if (type.IsGenericType) { type = type.GetGenericArguments()[0]; } var typeRuntime2 = TypeRuntimeInfoCache.GetRuntimeInfo(type); builder.AppendTable(typeRuntime2.TableSchema, typeRuntime2.TableFullName, typeRuntime2.IsTemporary); builder.Append(" "); builder.Append(alias2); bool withNoLock = !typeRuntime2.IsTemporary && _isNoLock && !string.IsNullOrEmpty(_withNoLock); if (withNoLock) { builder.Append(' '); builder.Append(_withNoLock); } builder.Append(" ON "); for (int i = 0; i < attribute.InnerKeys.Length; i++) { if (attribute.InnerKeys[i].StartsWith(AppConst.CONSTANT_FOREIGNKEY, StringComparison.Ordinal)) { builder.Append(attribute.InnerKeys[i].Substring(7)); } else { builder.Append(alias1); builder.Append('.'); builder.AppendMember(attribute.InnerKeys[i]); } builder.Append(" = "); if (attribute.OuterKeys[i].StartsWith(AppConst.CONSTANT_FOREIGNKEY, StringComparison.Ordinal)) { builder.Append(attribute.OuterKeys[i].Substring(7)); } else { builder.Append(alias2); builder.Append('.'); builder.AppendMember(attribute.OuterKeys[i]); } if (i < attribute.InnerKeys.Length - 1) { builder.Append(" AND "); } } if (nav.Predicate != null) { string alias = _ag.GetNavTableAlias(nav.Key); var visitor = new NavPredicateExpressionVisitor(_ag, builder, alias); visitor.Visit(nav.Predicate); } } }
/// <summary> /// 初始化 <see cref="JoinExpressionVisitor"/> 类的新实例 /// </summary> /// <param name="ag">表别名解析器</param> /// <param name="builder">SQL 语句生成器</param> public JoinExpressionVisitor(AliasGenerator ag, ISqlBuilder builder) : base(ag, builder) { _ag = ag; _builder = builder; }
/// <summary> /// 初始化 <see cref="NpgWhereExpressionVisitor"/> 类的新实例 /// </summary> /// <param name="ag">表别名解析器</param> /// <param name="builder">SQL 语句生成器</param> public NpgWhereExpressionVisitor(AliasGenerator ag, ISqlBuilder builder) : base(ag, builder) { _builder = builder; }
// 获取 LEFT JOIN / INNER JOIN 子句关联表的的别名 private void PrepareJoinAlias(DbExpression dbExpression, AliasGenerator ag) { Type type = dbExpression.Expressions[0].Type.GetGenericArguments()[0]; string name = TypeRuntimeInfoCache.GetRuntimeInfo(type).TableFullName; string outerAlias = null; // on a.Name equals b.Name 或 on new{ Name = a.Name,Id=a.Id } equals new { Name = b.Name,Id=b.Id } var left = dbExpression.Expressions[1] as LambdaExpression; var right = dbExpression.Expressions[2] as LambdaExpression; if (left.Body.NodeType == ExpressionType.New) { var body1 = left.Body as NewExpression; var body2 = right.Body as NewExpression; for (int index = 0; index < body1.Arguments.Count; ++index) { ag.GetTableAlias(body1.Arguments[index]); } for (int index = 0; index < body2.Arguments.Count; ++index) { string alias = ag.GetTableAlias(body2.Arguments[index]); outerAlias = alias; // 记录显示指定的LEFT JOIN 表别名 ag.AddJoinTableAlias(name, alias); } } else if (left.Body.NodeType == ExpressionType.MemberInit) { var body1 = left.Body as MemberInitExpression; var body2 = right.Body as MemberInitExpression; for (int index = 0; index < body1.Bindings.Count; ++index) { ag.GetTableAlias((body1.Bindings[index] as MemberAssignment).Expression); } for (int index = 0; index < body2.Bindings.Count; ++index) { string alias = ag.GetTableAlias((body2.Bindings[index] as MemberAssignment).Expression); outerAlias = alias; // 记录显示指定的LEFT JOIN 表别名 ag.AddJoinTableAlias(name, alias); } } else { ag.GetTableAlias(dbExpression.Expressions[1]); string alias = ag.GetTableAlias(dbExpression.Expressions[2]); outerAlias = alias; // 记录显示指定的LEFT JOIN 表别名 ag.AddJoinTableAlias(name, alias); } // 由 GetTable 重载指定的导航属性表别名 if (dbExpression.Expressions.Length > 4) { if (string.IsNullOrEmpty(outerAlias) || outerAlias == AliasGenerator.EMPTYNAME) { var lambda = dbExpression.Expressions[3] as LambdaExpression; string alias = ag.GetTableAlias(lambda.Parameters[1]); outerAlias = alias; // 记录显示指定的LEFT JOIN 表别名 ag.AddJoinTableAlias(name, alias); } var member = (dbExpression.Expressions[4] as LambdaExpression).Body as MemberExpression; string keyId = member.GetKeyWidthoutAnonymous(); // 记录GetTable<,>(path)指定的表别名 ag.AddGetTableAlias(keyId, outerAlias); } }
/// <summary> /// 添加导航属性关联 /// </summary> protected override void TanslateNavMember() { if (this.NavMembers == null || this.NavMembers.Count == 0) { return; } // 如果有一对多的导航属性,肯定会产生嵌套查询。那么内层查询别名肯定是t0,所以需要清掉 if (this.HasMany) { _aliasGenerator = new AliasGenerator(_aliasGenerator.ReserveQty); } //开始产生 USING 子句 ISqlBuilder jf = this.JoinFragment; int index = -1; // 未生成USING子句 if (_aliasGenerator.ReserveQty <= 1) { jf.AppendNewLine(); jf.Append(_keywordName); } else { jf.Append(','); jf.AppendNewLine(); } foreach (var nav in this.NavMembers) { index++; string key = nav.Key; MemberExpression m = nav.Expression; TypeRuntimeInfo typeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(m.Expression.Type); ForeignKeyAttribute attribute = typeRuntime.GetMemberAttribute <ForeignKeyAttribute>(m.Member.Name); string innerKey = string.Empty; string outerKey = key; string innerAlias = string.Empty; if (!m.Expression.Visitable()) { innerKey = m.Expression.NodeType == ExpressionType.Parameter ? (m.Expression as ParameterExpression).Name : (m.Expression as MemberExpression).Member.Name; } else { MemberExpression mLeft = null; if (m.Expression.NodeType == ExpressionType.MemberAccess) { mLeft = m.Expression as MemberExpression; } else if (m.Expression.NodeType == ExpressionType.Call) { mLeft = (m.Expression as MethodCallExpression).Object as MemberExpression; } string name = TypeRuntimeInfoCache.GetRuntimeInfo(mLeft.Type).TableFullName; innerAlias = _aliasGenerator.GetJoinTableAlias(name); if (string.IsNullOrEmpty(innerAlias)) { string keyLeft = mLeft.GetKeyWidthoutAnonymous(); if (this.NavMembers.Contains(keyLeft)) { innerKey = keyLeft; } innerAlias = _aliasGenerator.GetNavTableAlias(innerKey); } } string alias1 = !string.IsNullOrEmpty(innerAlias) ? innerAlias : _aliasGenerator.GetTableAlias(innerKey); string alias2 = _aliasGenerator.GetNavTableAlias(outerKey); // 补充与USING字符串同等间距的空白 if (_aliasGenerator.ReserveQty > 1 || index > 0) { jf.Append(_pad); } Type type = m.Type; var typeRumtime2 = TypeRuntimeInfoCache.GetRuntimeInfo(type); if (type.IsGenericType) { type = type.GetGenericArguments()[0]; } jf.AppendTable(typeRumtime2.TableSchema, typeRumtime2.TableName, typeRumtime2.IsTemporary); jf.Append(' '); jf.Append(alias2); if (_onPhrase.Length > 0) { _onPhrase.Append(" AND "); } for (int i = 0; i < attribute.InnerKeys.Length; i++) { if (attribute.InnerKeys[i].StartsWith(AppConst.CONSTANT_FOREIGNKEY, StringComparison.Ordinal)) { _onPhrase.Append(attribute.InnerKeys[i].Substring(7)); } else { _onPhrase.Append(alias1); _onPhrase.Append('.'); _onPhrase.AppendMember(attribute.InnerKeys[i]); } _onPhrase.Append(" = "); if (attribute.OuterKeys[i].StartsWith(AppConst.CONSTANT_FOREIGNKEY, StringComparison.Ordinal)) { _onPhrase.Append(attribute.OuterKeys[i].Substring(7)); } else { _onPhrase.Append(alias2); _onPhrase.Append('.'); _onPhrase.AppendMember(attribute.OuterKeys[i]); } } if (nav.Predicate != null) { string alias = _aliasGenerator.GetNavTableAlias(nav.Key); var visitor = new NavPredicateExpressionVisitor(_aliasGenerator, _onPhrase, alias); visitor.Visit(nav.Predicate); } if (index < this.NavMembers.Count - 1) { jf.Append(','); jf.AppendNewLine(); } } }
/// <summary> /// 初始化 <see cref="GroupByExpressionVisitor"/> 类的新实例 /// </summary> /// <param name="ag">表别名解析器</param> /// <param name="builder">SQL 语句生成器</param> public GroupByExpressionVisitor(AliasGenerator ag, ISqlBuilder builder) : base(ag, builder) { _builder = builder; }
/// <summary> /// 初始化 <see cref="NavPredicateExpressionVisitor"/> 类的新实例 /// </summary> /// <param name="ag">表别名解析器</param> /// <param name="builder">SQL 语句生成器</param> /// <param name="alias">指定的表别名</param> public NavPredicateExpressionVisitor(AliasGenerator ag, ISqlBuilder builder, string alias) : base(ag, builder) { _alias = alias; _builder = builder; }
/// <summary> /// 初始化 <see cref="OracleColumnExpressionVisitor"/> 类的新实例 /// </summary> /// <param name="ag">表别名解析器</param> /// <param name="builder">SQL 语句生成器</param> /// <param name="tree">查询语义</param> public OracleColumnExpressionVisitor(AliasGenerator ag, ISqlBuilder builder, DbQuerySelectTree tree) : base(ag, builder, tree) { _tree = tree; _builder = builder; }
/// <summary> /// 初始化 <see cref="HavingExpressionVisitor"/> 类的新实例 /// </summary> /// <param name="ag">表别名解析器</param> /// <param name="builder">SQL 语句生成器</param> /// <param name="groupBy">GROUP BY 子句</param> public HavingExpressionVisitor(AliasGenerator ag, ISqlBuilder builder, DbExpression groupBy) : base(ag, builder) { _groupBy = groupBy; _builder = builder; }