public SqlField(SqlField field) : this(field.SystemType, field.Name, field.PhysicalName, field.Nullable, field.PrimaryKeyOrder, field._nonUpdatableAttribute, field.MemberMapper) { }
IQueryElement ConvertInternal(IQueryElement element, ConvertFunc action) { if (element == null) { return(null); } IQueryElement newElement; if (_visitedElements.TryGetValue(element, out newElement)) { return(newElement); } switch (element.ElementType) { case QueryElementType.SqlFunction: { var func = (SqlFunction)element; var parms = Convert(func.Parameters, action); if (parms != null && !ReferenceEquals(parms, func.Parameters)) { newElement = new SqlFunction(func.SystemType, func.Name, func.Precedence, parms); } break; } case QueryElementType.SqlExpression: { var expr = (SqlExpression)element; var parameter = Convert(expr.Parameters, action); if (parameter != null && !ReferenceEquals(parameter, expr.Parameters)) { newElement = new SqlExpression(expr.SystemType, expr.Expr, expr.Precedence, parameter); } break; } case QueryElementType.SqlBinaryExpression: { var bexpr = (SqlBinaryExpression)element; var expr1 = (ISqlExpression)ConvertInternal(bexpr.Expr1, action); var expr2 = (ISqlExpression)ConvertInternal(bexpr.Expr2, action); if (expr1 != null && !ReferenceEquals(expr1, bexpr.Expr1) || expr2 != null && !ReferenceEquals(expr2, bexpr.Expr2)) { newElement = new SqlBinaryExpression(bexpr.SystemType, expr1 ?? bexpr.Expr1, bexpr.Operation, expr2 ?? bexpr.Expr2, bexpr.Precedence); } break; } case QueryElementType.SqlTable: { var table = (SqlTable)element; var fields1 = ToArray(table.Fields); var fields2 = Convert(fields1, action, f => new SqlField(f)); var joins = Convert(table.Joins, action, j => j.Clone()); var targs = table.TableArguments == null ? null : Convert(table.TableArguments, action); var fe = fields2 == null || ReferenceEquals(fields1, fields2); var je = joins == null || ReferenceEquals(table.Joins, joins); var ta = ReferenceEquals(table.TableArguments, targs); if (!fe || !je || !ta) { if (fe) { fields2 = fields1; for (var i = 0; i < fields2.Length; i++) { var field = fields2[i]; fields2[i] = new SqlField(field); _visitedElements[field] = fields2[i]; } } newElement = new SqlTable(table, fields2, joins ?? table.Joins, targs ?? table.TableArguments); _visitedElements[((SqlTable)newElement).All] = table.All; } break; } case QueryElementType.Join: { var join = (Join)element; var ons = Convert(join.JoinOns, action); if (ons != null && !ReferenceEquals(join.JoinOns, ons)) { newElement = new Join(join.TableName, join.Alias, ons); } break; } case QueryElementType.Column: { var col = (SqlQuery.Column)element; var expr = (ISqlExpression)ConvertInternal(col.Expression, action); IQueryElement parent; _visitedElements.TryGetValue(col.Parent, out parent); if (parent != null || expr != null && !ReferenceEquals(expr, col.Expression)) { newElement = new SqlQuery.Column(parent == null ? col.Parent : (SqlQuery)parent, expr ?? col.Expression, col._alias); } break; } case QueryElementType.TableSource: { var table = (SqlQuery.TableSource)element; var source = (ISqlTableSource)ConvertInternal(table.Source, action); var joins = Convert(table.Joins, action); if (source != null && !ReferenceEquals(source, table.Source) || joins != null && !ReferenceEquals(table.Joins, joins)) { newElement = new SqlQuery.TableSource(source ?? table.Source, table._alias, joins ?? table.Joins); } break; } case QueryElementType.JoinedTable: { var join = (SqlQuery.JoinedTable)element; var table = (SqlQuery.TableSource)ConvertInternal(join.Table, action); var cond = (SqlQuery.SearchCondition)ConvertInternal(join.Condition, action); if (table != null && !ReferenceEquals(table, join.Table) || cond != null && !ReferenceEquals(cond, join.Condition)) { newElement = new SqlQuery.JoinedTable(join.JoinType, table ?? join.Table, join.IsWeak, cond ?? join.Condition); } break; } case QueryElementType.SearchCondition: { var sc = (SqlQuery.SearchCondition)element; var conds = Convert(sc.Conditions, action); if (conds != null && !ReferenceEquals(sc.Conditions, conds)) { newElement = new SqlQuery.SearchCondition(conds); } break; } case QueryElementType.Condition: { var c = (SqlQuery.Condition)element; var p = (ISqlPredicate)ConvertInternal(c.Predicate, action); if (p != null && !ReferenceEquals(c.Predicate, p)) { newElement = new SqlQuery.Condition(c.IsNot, p, c.IsOr); } break; } case QueryElementType.ExprPredicate: { var p = (SqlQuery.Predicate.Expr)element; var e = (ISqlExpression)ConvertInternal(p.Expr1, action); if (e != null && !ReferenceEquals(p.Expr1, e)) { newElement = new SqlQuery.Predicate.Expr(e, p.Precedence); } break; } case QueryElementType.NotExprPredicate: { var p = (SqlQuery.Predicate.NotExpr)element; var e = (ISqlExpression)ConvertInternal(p.Expr1, action); if (e != null && !ReferenceEquals(p.Expr1, e)) { newElement = new SqlQuery.Predicate.NotExpr(e, p.IsNot, p.Precedence); } break; } case QueryElementType.ExprExprPredicate: { var p = (SqlQuery.Predicate.ExprExpr)element; var e1 = (ISqlExpression)ConvertInternal(p.Expr1, action); var e2 = (ISqlExpression)ConvertInternal(p.Expr2, action); if (e1 != null && !ReferenceEquals(p.Expr1, e1) || e2 != null && !ReferenceEquals(p.Expr2, e2)) { newElement = new SqlQuery.Predicate.ExprExpr(e1 ?? p.Expr1, p.Operator, e2 ?? p.Expr2); } break; } case QueryElementType.LikePredicate: { var p = (SqlQuery.Predicate.Like)element; var e1 = (ISqlExpression)ConvertInternal(p.Expr1, action); var e2 = (ISqlExpression)ConvertInternal(p.Expr2, action); var es = (ISqlExpression)ConvertInternal(p.Escape, action); if (e1 != null && !ReferenceEquals(p.Expr1, e1) || e2 != null && !ReferenceEquals(p.Expr2, e2) || es != null && !ReferenceEquals(p.Escape, es)) { newElement = new SqlQuery.Predicate.Like(e1 ?? p.Expr1, p.IsNot, e2 ?? p.Expr2, es ?? p.Escape); } break; } case QueryElementType.BetweenPredicate: { var p = (SqlQuery.Predicate.Between)element; var e1 = (ISqlExpression)ConvertInternal(p.Expr1, action); var e2 = (ISqlExpression)ConvertInternal(p.Expr2, action); var e3 = (ISqlExpression)ConvertInternal(p.Expr3, action); if (e1 != null && !ReferenceEquals(p.Expr1, e1) || e2 != null && !ReferenceEquals(p.Expr2, e2) || e3 != null && !ReferenceEquals(p.Expr3, e3)) { newElement = new SqlQuery.Predicate.Between(e1 ?? p.Expr1, p.IsNot, e2 ?? p.Expr2, e3 ?? p.Expr3); } break; } case QueryElementType.IsNullPredicate: { var p = (SqlQuery.Predicate.IsNull)element; var e = (ISqlExpression)ConvertInternal(p.Expr1, action); if (e != null && !ReferenceEquals(p.Expr1, e)) { newElement = new SqlQuery.Predicate.IsNull(e, p.IsNot); } break; } case QueryElementType.InSubQueryPredicate: { var p = (SqlQuery.Predicate.InSubQuery)element; var e = (ISqlExpression)ConvertInternal(p.Expr1, action); var q = (SqlQuery)ConvertInternal(p.SubQuery, action); if (e != null && !ReferenceEquals(p.Expr1, e) || q != null && !ReferenceEquals(p.SubQuery, q)) { newElement = new SqlQuery.Predicate.InSubQuery(e ?? p.Expr1, p.IsNot, q ?? p.SubQuery); } break; } case QueryElementType.InListPredicate: { var p = (SqlQuery.Predicate.InList)element; var e = (ISqlExpression)ConvertInternal(p.Expr1, action); var v = Convert(p.Values, action); if (e != null && !ReferenceEquals(p.Expr1, e) || v != null && !ReferenceEquals(p.Values, v)) { newElement = new SqlQuery.Predicate.InList(e ?? p.Expr1, p.IsNot, v ?? p.Values); } break; } case QueryElementType.FuncLikePredicate: { var p = (SqlQuery.Predicate.FuncLike)element; var f = (SqlFunction)ConvertInternal(p.Function, action); if (f != null && !ReferenceEquals(p.Function, f)) { newElement = new SqlQuery.Predicate.FuncLike(f); } break; } case QueryElementType.SetExpression: { var s = (SqlQuery.SetExpression)element; var c = (ISqlExpression)ConvertInternal(s.Column, action); var e = (ISqlExpression)ConvertInternal(s.Expression, action); if (c != null && !ReferenceEquals(s.Column, c) || e != null && !ReferenceEquals(s.Expression, e)) { newElement = new SqlQuery.SetExpression(c ?? s.Column, e ?? s.Expression); } break; } case QueryElementType.SetClause: { var s = (SqlQuery.SetClause)element; var t = s.Into != null ? (SqlTable)ConvertInternal(s.Into, action) : null; var i = Convert(s.Items, action); if (t != null && !ReferenceEquals(s.Into, t) || i != null && !ReferenceEquals(s.Items, i)) { var sc = new SqlQuery.SetClause(); sc.Into = t ?? sc.Into; sc.Items.AddRange(i ?? s.Items); sc.WithIdentity = s.WithIdentity; newElement = sc; } break; } case QueryElementType.SelectClause: { var sc = (SqlQuery.SelectClause)element; var cols = Convert(sc.Columns, action); var take = (ISqlExpression)ConvertInternal(sc.TakeValue, action); var skip = (ISqlExpression)ConvertInternal(sc.SkipValue, action); IQueryElement parent; _visitedElements.TryGetValue(sc.SqlQuery, out parent); if (parent != null || cols != null && !ReferenceEquals(sc.Columns, cols) || take != null && !ReferenceEquals(sc.TakeValue, take) || skip != null && !ReferenceEquals(sc.SkipValue, skip)) { newElement = new SqlQuery.SelectClause(sc.IsDistinct, take ?? sc.TakeValue, skip ?? sc.SkipValue, cols ?? sc.Columns); ((SqlQuery.SelectClause)newElement).SetSqlQuery((SqlQuery)parent); } break; } case QueryElementType.FromClause: { var fc = (SqlQuery.FromClause)element; var ts = Convert(fc.Tables, action); IQueryElement parent; _visitedElements.TryGetValue(fc.SqlQuery, out parent); if (parent != null || ts != null && !ReferenceEquals(fc.Tables, ts)) { newElement = new SqlQuery.FromClause(ts ?? fc.Tables); ((SqlQuery.FromClause)newElement).SetSqlQuery((SqlQuery)parent); } break; } case QueryElementType.WhereClause: { var wc = (SqlQuery.WhereClause)element; var cond = (SqlQuery.SearchCondition)ConvertInternal(wc.SearchCondition, action); IQueryElement parent; _visitedElements.TryGetValue(wc.SqlQuery, out parent); if (parent != null || cond != null && !ReferenceEquals(wc.SearchCondition, cond)) { newElement = new SqlQuery.WhereClause(cond ?? wc.SearchCondition); ((SqlQuery.WhereClause)newElement).SetSqlQuery((SqlQuery)parent); } break; } case QueryElementType.GroupByClause: { var gc = (SqlQuery.GroupByClause)element; var es = Convert(gc.Items, action); IQueryElement parent; _visitedElements.TryGetValue(gc.SqlQuery, out parent); if (parent != null || es != null && !ReferenceEquals(gc.Items, es)) { newElement = new SqlQuery.GroupByClause(es ?? gc.Items); ((SqlQuery.GroupByClause)newElement).SetSqlQuery((SqlQuery)parent); } break; } case QueryElementType.OrderByClause: { var oc = (SqlQuery.OrderByClause)element; var es = Convert(oc.Items, action); IQueryElement parent; _visitedElements.TryGetValue(oc.SqlQuery, out parent); if (parent != null || es != null && !ReferenceEquals(oc.Items, es)) { newElement = new SqlQuery.OrderByClause(es ?? oc.Items); ((SqlQuery.OrderByClause)newElement).SetSqlQuery((SqlQuery)parent); } break; } case QueryElementType.OrderByItem: { var i = (SqlQuery.OrderByItem)element; var e = (ISqlExpression)ConvertInternal(i.Expression, action); if (e != null && !ReferenceEquals(i.Expression, e)) { newElement = new SqlQuery.OrderByItem(e, i.IsDescending); } break; } case QueryElementType.Union: { var u = (SqlQuery.Union)element; var q = (SqlQuery)ConvertInternal(u.SqlQuery, action); if (q != null && !ReferenceEquals(u.SqlQuery, q)) { newElement = new SqlQuery.Union(q, u.IsAll); } break; } case QueryElementType.SqlQuery: { var q = (SqlQuery)element; IQueryElement parent = null; var doConvert = q.ParentSql != null && !_visitedElements.TryGetValue(q.ParentSql, out parent); if (!doConvert) { doConvert = null != Find(q, e => { if (_visitedElements.ContainsKey(e) && _visitedElements[e] != e) { return(true); } var ret = action(e); if (ret != null && !ReferenceEquals(e, ret)) { _visitedElements.Add(e, ret); return(true); } return(false); }); } if (!doConvert) { break; } var nq = new SqlQuery { QueryType = q.QueryType }; _visitedElements.Add(q, nq); var fc = (SqlQuery.FromClause)ConvertInternal(q.From, action) ?? q.From; var sc = (SqlQuery.SelectClause)ConvertInternal(q.Select, action) ?? q.Select; var tc = q.QueryType == QueryType.Update || q.QueryType == QueryType.Insert ? ((SqlQuery.SetClause)ConvertInternal(q.Set, action) ?? q.Set) : null; var wc = (SqlQuery.WhereClause)ConvertInternal(q.Where, action) ?? q.Where; var gc = (SqlQuery.GroupByClause)ConvertInternal(q.GroupBy, action) ?? q.GroupBy; var hc = (SqlQuery.WhereClause)ConvertInternal(q.Having, action) ?? q.Having; var oc = (SqlQuery.OrderByClause)ConvertInternal(q.OrderBy, action) ?? q.OrderBy; var us = q.HasUnion ? Convert(q.Unions, action) : q.Unions; var ps = new List <SqlParameter>(q.Parameters.Count); foreach (var p in q.Parameters) { IQueryElement e; if (_visitedElements.TryGetValue(p, out e)) { if (e == null) { ps.Add(p); } else if (e is SqlParameter) { ps.Add((SqlParameter)e); } } } nq.Init(tc, sc, fc, wc, gc, hc, oc, us, (SqlQuery)parent, q.ParameterDependent, ps); _visitedElements[q] = action(nq) ?? nq; return(nq); } } newElement = newElement == null?action(element) : (action(newElement) ?? newElement); _visitedElements.Add(element, newElement); return(newElement); }