private void AddTablesForPagedCollection <T>( SelectQuery <T> selectQuery, StringBuilder innerTableSql, StringBuilder outerTableSql, StringBuilder innerColumnSql, StringBuilder outerColumnSql, FetchNode rootNode) where T : class, new() { innerTableSql.Append(" from "); this.Dialect.AppendQuotedTableName(innerTableSql, this.Configuration.GetMap <T>()); innerTableSql.Append(" as t"); if (selectQuery.IsForUpdate) { this.Dialect.AppendForUpdateUsingTableHint(innerTableSql); } // go through the tree and generate the sql var signatureBuilder = new StringBuilder(); var splitOns = new List <string>(); foreach (var node in rootNode.Children) { var signature = this.AddNodeForPagedCollection(node.Value, innerTableSql, outerTableSql, innerColumnSql, outerColumnSql, false); if (node.Value.IsFetched) { signatureBuilder.Append(signature.Signature); splitOns.AddRange(signature.SplitOn); } } rootNode.FetchSignature = signatureBuilder.ToString(); rootNode.SplitOn = string.Join(",", splitOns); }
private static FetchNode InnerClone(FetchNode progenitor, FetchNode parent) { var clone = new FetchNode { Alias = progenitor.Alias, ContainedCollectionfetchesCount = progenitor.ContainedCollectionfetchesCount, FetchSignature = progenitor.FetchSignature, InferredInnerJoin = progenitor.InferredInnerJoin, IsFetched = progenitor.IsFetched, SplitOn = progenitor.SplitOn, Column = progenitor.Column, Parent = parent }; clone.Root = parent?.Root ?? clone; var clonedChildren = new OrderedDictionary <string, FetchNode>(); foreach (var keyValue in progenitor.Children) { clonedChildren.Add(keyValue.Key, InnerClone(keyValue.Value, clone)); } clone.Children = clonedChildren; return(clone); }
private string GetOrderClauseInner <T>( OrderClause <T> clause, FetchNode rootNode, Func <IColumn, FetchNode, string> aliasRewriter, Func <IColumn, FetchNode, string> nameRewriter, out bool isRootPrimaryKeyClause) { var lambdaExpression = clause.Expression as LambdaExpression; if (lambdaExpression == null) { throw new InvalidOperationException("OrderBy clauses must be LambdaExpressions"); } var node = this.VisitExpression(lambdaExpression.Body, rootNode); var sb = new StringBuilder(); if (node == null) { var column = this.configuration.GetMap <T>().Columns[((MemberExpression)lambdaExpression.Body).Member.Name]; this.dialect.AppendQuotedName(sb, nameRewriter != null ? nameRewriter(column, node) : column.DbName); sb.Append(" ").Append(clause.Direction == ListSortDirection.Ascending ? "asc" : "desc"); isRootPrimaryKeyClause = column.IsPrimaryKey; } else { IColumn column = null; if (ReferenceEquals(node, rootNode)) { column = this.configuration.GetMap <T>().Columns[((MemberExpression)lambdaExpression.Body).Member.Name]; isRootPrimaryKeyClause = column.IsPrimaryKey; } else { if (node.Column.Relationship == RelationshipType.ManyToOne) { column = node.Column.ParentMap.Columns[((MemberExpression)lambdaExpression.Body).Member.Name]; } else if (node.Column.Relationship == RelationshipType.OneToOne) { column = node.Column.OppositeColumn.Map.Columns[((MemberExpression)lambdaExpression.Body).Member.Name]; } else { throw new NotSupportedException(); } isRootPrimaryKeyClause = false; } sb.Append(aliasRewriter != null ? aliasRewriter(column, node) : node.Alias).Append("."); this.dialect.AppendQuotedName(sb, nameRewriter != null ? nameRewriter(column, node) : column.DbName); sb.Append(" ").Append(clause.Direction == ListSortDirection.Ascending ? "asc" : "desc"); } return(sb.ToString()); }
protected void AddNode(FetchNode node, StringBuilder tableSql) { var map = this.GetMapForNode(node); this.AddTableSqlForNode(node, map, tableSql); foreach (var child in node.Children) { this.AddNode(child.Value, tableSql); } }
private void AppendDefaultOrderBy <T>(FetchNode rootNode, StringBuilder orderSql, string alias = null, string name = null) { orderSql.Append(" order by "); if (rootNode != null) { orderSql.Append(alias ?? rootNode.Alias); orderSql.Append('.'); } this.Dialect.AppendQuotedName(orderSql, name ?? this.Configuration.GetMap <T>().PrimaryKey.DbName); }
public FetchNode AddChild(IColumn column, bool isFetched) { // create the node var newNode = new FetchNode { Alias = "t_" + (isFetched ? ++this.Root.aliasCounter : ++this.Root.nonFetchedAliasCounter), IsFetched = isFetched, Parent = this, Root = this.Root, Column = column }; if (column.Relationship == RelationshipType.OneToMany) { // go through and increase the number of contained collections in each parent node var parent = this; while (parent != null) { ++parent.ContainedCollectionfetchesCount; parent = parent.Parent; } } // insert it if (this.Children.Any()) { var i = 0; var inserted = false; foreach (var child in this.Children) { if (child.Value.Column.FetchId > newNode.Column.FetchId) { this.Children.Insert(i, new KeyValuePair <string, FetchNode>(column.Name, newNode)); inserted = true; break; } ++i; } if (!inserted) { this.Children.Add(column.Name, newNode); } } else { this.Children.Add(column.Name, newNode); } return(newNode); }
protected AddNodeResult AddNode(FetchNode node, StringBuilder tableSql, StringBuilder columnSql, bool selectQueryFetchAllProperties, bool isProjectedQuery) { // add this node and then it's children // add table sql var map = this.GetMapForNode(node); this.AddTableSqlForNode(node, map, tableSql); // add the columns var splitOns = new List <string>(); if (node.IsFetched) { var columns = GetColumnsWithIncludesAndExcludes(node.IncludedColumns, node.ExcludedColumns, map, selectQueryFetchAllProperties, isProjectedQuery); columns = columns.Where( c => !node.Children.ContainsKey(c.Name) || !node.Children[c.Name] .IsFetched); foreach (var columnEntry in columns.AsSmartEnumerable()) { columnSql.Append(", "); this.AddColumn(columnSql, columnEntry.Value, node.Alias); if (columnEntry.IsFirst) { splitOns.Add(columnEntry.Value.Name); } } } // add its children var signatureBuilder = new StringBuilder(); foreach (var child in node.Children) { var signature = this.AddNode(child.Value, tableSql, columnSql, selectQueryFetchAllProperties, isProjectedQuery); if (child.Value.IsFetched) { signatureBuilder.Append(signature.Signature); splitOns.AddRange(signature.SplitOn); } } var actualSignature = signatureBuilder.ToString(); if (node.IsFetched) { actualSignature = node.Column.FetchId + "S" + actualSignature + "E"; } return(new AddNodeResult { Signature = actualSignature, SplitOn = splitOns }); }
private void GetOrCreateCurrentNode(PropertyInfo propInfo, Type declaringType) { this.currentFetchStack.Add(propInfo); if (!this.currentNode.Children.ContainsKey(propInfo.Name)) { this.currentNode = this.currentNode.AddChild(this.config.GetMap(declaringType).Columns[propInfo.Name], false); } else { this.currentNode = this.currentNode.Children[propInfo.Name]; } }
private ISqlElement VisitParameter(ParameterExpression exp) { if (this.isTopOfBinaryOrMethod) { this.isEntityFetch = true; this.entityFetchType = exp.Type; return(new ColumnElement(this.modifiedRootNode, this.config.GetMap(exp.Type).PrimaryKey.DbName, true)); } this.currentNode = this.modifiedRootNode; return(null); }
public void ParseExpression <TBase>(Expression expression, FetchNode rootNode, bool isInclude) { var lambda = expression as LambdaExpression; if (lambda == null) { throw new InvalidOperationException("Include and Exclude expressions must be LambdaExpressions"); } var node = this.VisitExpression(lambda.Body, rootNode); IMap map; if (ReferenceEquals(node, rootNode)) { map = this.configuration.GetMap <TBase>(); } else { if (node.Column.Relationship == RelationshipType.ManyToOne) { map = node.Column.ParentMap; } else if (node.Column.Relationship == RelationshipType.OneToOne) { map = node.Column.OppositeColumn.Map; } else { throw new NotSupportedException("Include/Exclude clauses can only use Many to One and One to One relationships"); } } var column = map.Columns[((MemberExpression)lambda.Body).Member.Name]; if (column.Relationship != RelationshipType.None) { throw new NotSupportedException("Include/Exclude clauses must end with a property that is a non-relationship type property e.g. a string"); } if (isInclude && node.IncludedColumns == null) { node.IncludedColumns = new List <IColumn>(); } else if (!isInclude && node.ExcludedColumns == null) { node.ExcludedColumns = new List <IColumn>(); } (isInclude ? node.IncludedColumns : node.ExcludedColumns).Add(column); }
private bool HasAnyNullableAncestor(FetchNode node) { if (node.Column == null) { return(false); } if (node.Column.IsNullable && !node.InferredInnerJoin) { return(true); } return(this.HasAnyNullableAncestor(node.Parent)); }
private string GetMultiTableDeleteQuery <T>(StringBuilder whereSql, FetchNode rootNode) { var map = this.Configuration.GetMap <T>(); var sql = new StringBuilder(); sql.Append("delete t from "); this.Dialect.AppendQuotedTableName(sql, map); sql.Append(" as t"); foreach (var node in rootNode.Children) { this.AddNode(node.Value, sql); } sql.Append(whereSql); return(sql.ToString()); }
private void AddTablesForNoPagingUnion <T>( SelectQuery <T> selectQuery, StringBuilder outerQueryColumnSql, StringBuilder[] subQueryColumnSqls, StringBuilder[] subQueryTableSqls, FetchNode rootNode) where T : class, new() { foreach (var subQuery in subQueryTableSqls) { subQuery.Append(" from "); this.Dialect.AppendQuotedTableName(subQuery, this.Configuration.GetMap <T>()); subQuery.Append(" as t"); if (selectQuery.IsForUpdate) { this.Dialect.AppendForUpdateUsingTableHint(subQuery); } } // go through the tree and generate the sql var signatureBuilder = new StringBuilder(); var splitOns = new List <string>(); var insideQueryN = 0; var hasSeenFirstCollection = false; foreach (var node in rootNode.Children) { var signature = this.AddNodeForNonPagedUnion( node.Value, outerQueryColumnSql, subQueryColumnSqls, subQueryTableSqls, ref insideQueryN, false, ref hasSeenFirstCollection); if (node.Value.IsFetched) { signatureBuilder.Append(signature.Signature); splitOns.AddRange(signature.SplitOn); } } rootNode.FetchSignature = signatureBuilder.ToString(); rootNode.SplitOn = string.Join(",", splitOns); }
public SelectWriterResult GenerateSql <T>(IEnumerable <Expression <Func <T, bool> > > whereClauses, FetchNode rootNode) { if (whereClauses.IsEmpty()) { return(new SelectWriterResult(string.Empty, null, rootNode)); } this.InitVariables(); this.modifiedRootNode = rootNode; foreach (var whereClause in whereClauses) { this.VisitWhereClause(whereClause); this.sqlElements.Enqueue(new StringElement(" and ")); } return(new SelectWriterResult(this.GetSql(), this.parameters, this.modifiedRootNode)); }
private void GetOrCreateCurrentNode(PropertyInfo propInfo, Type declaringType) { if (!this.currentNode.Children.ContainsKey(propInfo.Name)) { // create the node var newNode = new FetchNode { Alias = "t_" + ++this.aliasCounter, IsFetched = false, Parent = this.currentNode, Column = this.config.GetMap(declaringType).Columns[propInfo.Name] }; if (this.currentNode.Children.Any()) { var i = 0; var inserted = false; foreach (var child in this.currentNode.Children) { if (child.Value.Column.FetchId > newNode.Column.FetchId) { this.currentNode.Children.Insert(i, new KeyValuePair <string, FetchNode>(propInfo.Name, newNode)); inserted = true; break; } ++i; } if (!inserted) { this.currentNode.Children.Add(propInfo.Name, newNode); } } else { this.currentNode.Children.Add(propInfo.Name, newNode); } this.currentNode = newNode; } else { this.currentNode = this.currentNode.Children[propInfo.Name]; } }
private void EnsureRootNodeExists() { if (this.modifiedRootNode == null) { this.modifiedRootNode = new FetchNode(); // update exising ISqlElements to use new rootnode (and alias) foreach (var element in this.sqlElements) { var columnElement = element as ColumnElement; if (columnElement != null && columnElement.IsRoot) { columnElement.Node = this.modifiedRootNode; } } this.currentNode = this.modifiedRootNode; } }
private IMap GetMapForNode(FetchNode node) { IMap map; if (node.Column.Relationship == RelationshipType.OneToMany) { map = this.Configuration.GetMap(node.Column.Type.GetGenericArguments()[0]); } else if (node.Column.Relationship == RelationshipType.ManyToOne || node.Column.Relationship == RelationshipType.OneToOne) { map = this.Configuration.GetMap(node.Column.Type); } else { throw new NotSupportedException(); } return(map); }
public string GetOrderClause <T>( OrderClause <T> clause, FetchNode rootNode, Func <IColumn, FetchNode, string> aliasRewriter, Func <IColumn, FetchNode, string> nameRewriter, out bool isRootPrimaryKeyClause) { if (aliasRewriter == null) { throw new ArgumentNullException("aliasRewriter"); } if (nameRewriter == null) { throw new ArgumentNullException("nameRewriter"); } return(this.GetOrderClauseInner(clause, rootNode, aliasRewriter, nameRewriter, out isRootPrimaryKeyClause)); }
public bool AddOrderByClause <T>( Queue <OrderClause <T> > orderClauses, StringBuilder sql, FetchNode rootNode, Func <IColumn, FetchNode, string> aliasRewriter = null, Func <IColumn, FetchNode, string> nameRewriter = null) { if (orderClauses.Count == 0) { return(false); } sql.Append(" order by "); var orderClauseWriter = new OrderClauseWriter(this.Configuration, this.Dialect); var containsRootPrimaryKeyClause = false; while (orderClauses.Count > 0) { var isRootPrimaryKeyClause = false; if (aliasRewriter == null && nameRewriter == null) { sql.Append(orderClauseWriter.GetOrderClause(orderClauses.Dequeue(), rootNode, out isRootPrimaryKeyClause)); } else { sql.Append( orderClauseWriter.GetOrderClause(orderClauses.Dequeue(), rootNode, aliasRewriter, nameRewriter, out isRootPrimaryKeyClause)); } if (orderClauses.Count > 0) { sql.Append(", "); } if (isRootPrimaryKeyClause) { containsRootPrimaryKeyClause = true; } } return(containsRootPrimaryKeyClause); }
private void AddTableSqlForNode(FetchNode node, IMap map, StringBuilder tableSql) { // if this is a non-nullable relationship and we've not already done a left join on the way to this node // we can do an inner join tableSql.Append( node.InferredInnerJoin || (!node.Column.IsNullable && node.Column.Relationship != RelationshipType.OneToMany && !this.HasAnyNullableAncestor(node.Parent)) ? " inner join " : " left join "); this.Dialect.AppendQuotedTableName(tableSql, map); tableSql.Append(" as " + node.Alias); if (node.Column.Relationship == RelationshipType.ManyToOne || node.Column.Relationship == RelationshipType.OneToOne) { tableSql.Append(" on " + node.Parent.Alias + "." + node.Column.DbName + " = " + node.Alias + "." + map.PrimaryKey.DbName); } else if (node.Column.Relationship == RelationshipType.OneToMany) { tableSql.Append(" on " + node.Parent.Alias + "." + node.Column.Map.PrimaryKey.DbName + " = " + node.Alias + "." + node.Column.ChildColumn.DbName); } }
private void AddPropertiesToFetchTree <T>( ref int aliasCounter, ref int numberCollectionFetches, Stack <string> entityNames, FetchNode currentNode, FetchNode rootNode) { while (entityNames.Count > 0) { var propName = entityNames.Pop(); // don't add duplicates if (!currentNode.Children.ContainsKey(propName)) { var column = this.configuration.GetMap( currentNode == rootNode ? typeof(T) : (currentNode.Column.Relationship == RelationshipType.OneToMany ? currentNode.Column.Type.GetGenericArguments().First() : currentNode.Column.Type)).Columns[propName]; if (column.IsIgnored) { //TODO we should probably warn at this point continue; } if (column.Relationship == RelationshipType.OneToMany) { ++numberCollectionFetches; } // add to tree currentNode = currentNode.AddChild(column, true); } else { currentNode = currentNode.Children[propName]; } } }
public SqlWriterResult GenerateBulkSql <T>(Action <T> updateAction, IEnumerable <Expression <Func <T, bool> > > predicates) where T : class, new() { var predicateArray = predicates as Expression <Func <T, bool> >[] ?? predicates?.ToArray(); // add where clause var whereSql = new StringBuilder(); var parameters = new AutoNamingDynamicParameters(); FetchNode rootNode = null; if (predicateArray != null) { this.AddWhereClause(predicateArray, whereSql, parameters, ref rootNode); } // run the update var entity = new T(); ((ISetLogger)entity).EnableSetLogging(); updateAction(entity); // find the set properties var setLogger = (ISetLogger)entity; var setProps = setLogger.GetSetProperties(); if (!setProps.Any()) { return(new SqlWriterResult(string.Empty, parameters)); } if (rootNode == null) { // the where clauses on are on the root table return(new SqlWriterResult(this.GetSimpleUpdateQuery(setProps, entity, parameters, whereSql), parameters)); } // cross table where clause return(new SqlWriterResult(this.GetMultiTableUpdateQuery(setProps, entity, parameters, whereSql, rootNode), parameters)); }
public SqlWriterResult GenerateBulkSql <T>(IEnumerable <Expression <Func <T, bool> > > predicates) { var predicateArray = predicates as Expression <Func <T, bool> >[] ?? predicates?.ToArray(); // add where clause var whereSql = new StringBuilder(); var parameters = new AutoNamingDynamicParameters(); FetchNode rootNode = null; if (predicateArray != null) { this.AddWhereClause(predicateArray, whereSql, parameters, ref rootNode); } if (rootNode == null) { // the where clauses were all on the root table return(new SqlWriterResult(this.GetSimpleDeleteQuery <T>(whereSql), parameters)); } // cross table where clause return(new SqlWriterResult(this.GetMultiTableDeleteQuery <T>(whereSql, rootNode), parameters)); }
protected FetchNode VisitExpression(Expression expr, FetchNode rootNode) { var memberExpr = expr as MemberExpression; if (memberExpr == null) { throw new InvalidOperationException("Order/Include/Exclude clauses must contain MemberExpressions"); } if (memberExpr.Expression.NodeType == ExpressionType.Parameter) { // we're at the bottom return(rootNode); // this should be the root node } // not at the bottom, find the child and return that var parentNode = this.VisitExpression(memberExpr.Expression, rootNode); if (parentNode == null) { throw new InvalidOperationException("You must Fetch a relationship if you want to use it in an order by or include/exclude clause"); } var baseExpr = memberExpr.Expression as MemberExpression; if (baseExpr == null) { throw new InvalidOperationException("Order/Include/Exclude clauses must contain MemberExpressions"); } if (!parentNode.Children.ContainsKey(baseExpr.Member.Name)) { throw new InvalidOperationException($"You must Fetch {baseExpr.Member.Name} if you wish to you it in an Order/Include/Exclude clause"); } return(parentNode.Children[baseExpr.Member.Name]); }
private FetchNode VisitOrderClause(Expression expr, FetchNode rootNode) { var memberExpr = expr as MemberExpression; if (memberExpr == null) { throw new InvalidOperationException("OrderBy clauses must contain MemberExpressions"); } if (memberExpr.Expression.NodeType == ExpressionType.Parameter) { // we're at the bottom return(rootNode); } // we're not at the bottom, find the child and return that var parentNode = this.VisitOrderClause(memberExpr.Expression, rootNode); if (parentNode == null) { throw new InvalidOperationException("You must Fetch a relationship if you wish to OrderBy it"); } var baseExpr = memberExpr.Expression as MemberExpression; if (baseExpr == null) { throw new InvalidOperationException("OrderBy clauses must contain MemberExpressions"); } if (!parentNode.Children.ContainsKey(baseExpr.Member.Name)) { throw new InvalidOperationException("You must Fetch a relationship if you wish to OrderBy it"); } return(parentNode.Children[baseExpr.Member.Name]); }
private static void AppendPagedUnionJoin(FetchNode node, StringBuilder subQuery) { if (node.Column.Relationship == RelationshipType.ManyToOne) { subQuery.Append(" on ") .Append(node.Parent.Alias) .Append(".") .Append(node.Column.DbName) .Append(" = ") .Append(node.Alias) .Append(".") .Append(node.Column.ParentMap.PrimaryKey.DbName); } else if (node.Column.Relationship == RelationshipType.OneToOne) { subQuery.Append(" on ") .Append(node.Parent.Alias) .Append(".") .Append(node.Column.Map.PrimaryKey.DbName) .Append(" = ") .Append(node.Alias) .Append(".") .Append(node.Column.OppositeColumn.DbName); } else { subQuery.Append(" on ") .Append(node.Parent.Alias) .Append(".") .Append(node.Column.Map.PrimaryKey.DbName) .Append(" = ") .Append(node.Alias) .Append(".") .Append(node.Column.ChildColumn.DbName); } }
public SelectWriterResult(string sql, DynamicParameters parameters, FetchNode fetchTree) : base(sql, parameters) { this.FetchTree = fetchTree; }
public string GetOrderClause <T>(OrderClause <T> clause, FetchNode rootNode, out bool isRootPrimaryKeyClause) { return(this.GetOrderClauseInner(clause, rootNode, null, null, out isRootPrimaryKeyClause)); }
private void AddPropertiesToFetchTree <T>( ref int aliasCounter, ref int numberCollectionFetches, Stack <string> entityNames, FetchNode currentNode, FetchNode rootNode) { while (entityNames.Count > 0) { var propName = entityNames.Pop(); // don't add duplicates if (!currentNode.Children.ContainsKey(propName)) { var column = this.configuration.GetMap( currentNode == rootNode ? typeof(T) : (currentNode.Column.Relationship == RelationshipType.OneToMany ? currentNode.Column.Type.GetGenericArguments().First() : currentNode.Column.Type)).Columns[propName]; if (column.IsIgnored) { //TODO we should probably warn at this point continue; } if (column.Relationship == RelationshipType.OneToMany) { ++numberCollectionFetches; } // add to tree var node = new FetchNode { Parent = currentNode, Column = column, Alias = "t_" + ++aliasCounter, IsFetched = true }; if (column.Relationship == RelationshipType.OneToMany) { // go through and increase the number of contained collections in each parent node var parent = node.Parent; while (parent != null) { ++parent.ContainedCollectionfetchesCount; parent = parent.Parent; } } // insert the node in the correct order (i.e. respecting the FetchId and then all other things that depend on this // should be constant if (currentNode.Children.Any()) { var i = 0; var inserted = false; foreach (var child in currentNode.Children) { if (child.Value.Column.FetchId > column.FetchId) { currentNode.Children.Insert(i, new KeyValuePair <string, FetchNode>(propName, node)); inserted = true; break; } i++; } if (!inserted) { currentNode.Children.Add(propName, node); } } else { currentNode.Children.Add(propName, node); } currentNode = node; } else { currentNode = currentNode.Children[propName]; } } }
public FetchNode GetFetchTree <T>(SelectQuery <T> selectQuery, out int aliasCounter, out int numberCollectionFetches) where T : class, new() { FetchNode rootNode = null; numberCollectionFetches = 0; aliasCounter = 0; if (selectQuery.HasFetches()) { // now we go through the fetches and generate the tree structure rootNode = new FetchNode { Alias = "t" }; foreach (var fetch in selectQuery.Fetches) { var lambda = fetch as LambdaExpression; if (lambda != null) { var expr = lambda.Body as MemberExpression; var currentNode = rootNode; var entityNames = new Stack <string>(); // TODO Change this so that algorithm only goes through tree once // We go through the fetch expression (backwards) while (expr != null) { entityNames.Push(expr.Member.Name); expr = expr.Expression as MemberExpression; } // Now go through the expression forwards adding in nodes where needed this.AddPropertiesToFetchTree <T>(ref aliasCounter, ref numberCollectionFetches, entityNames, currentNode, rootNode); } } // now iterate through the collection fetches foreach (var collectionFetch in selectQuery.CollectionFetches) { var entityNames = new Stack <string>(); var currentNode = rootNode; // start at the top of the stack, pop the expression off and do as above for (var i = collectionFetch.Value.Count - 1; i >= 0; i--) { var lambdaExpr = collectionFetch.Value[i] as LambdaExpression; if (lambdaExpr != null) { var expr = lambdaExpr.Body as MemberExpression; while (expr != null) { entityNames.Push(expr.Member.Name); expr = expr.Expression as MemberExpression; } } } // add in the initial fetch many var fetchManyLambda = collectionFetch.Key as LambdaExpression; if (fetchManyLambda != null) { var expr = fetchManyLambda.Body as MemberExpression; while (expr != null) { entityNames.Push(expr.Member.Name); expr = expr.Expression as MemberExpression; } } this.AddPropertiesToFetchTree <T>(ref aliasCounter, ref numberCollectionFetches, entityNames, currentNode, rootNode); } } return(rootNode); }
private void AddRootColumns <T>(SelectQuery <T> selectQuery, StringBuilder columnSql, FetchNode rootNode, IDictionary <Type, IList <IColumn> > includes, IDictionary <Type, IList <IColumn> > excludes, bool removeTrailingComma = true) where T : class, new() { var alias = rootNode != null ? rootNode.Alias : null; if (selectQuery.Projection == null) { var columns = GetColumnsWithIncludesAndExcludes(includes, excludes, this.Configuration.GetMap <T>(), selectQuery.FetchAllProperties); columns = columns.Where( c => rootNode == null || !rootNode.Children.ContainsKey(c.Name) || !rootNode.Children[c.Name] .IsFetched); foreach (var column in columns) { this.AddColumn(columnSql, column, alias); columnSql.Append(", "); } } if (removeTrailingComma) { columnSql.Remove(columnSql.Length - 2, 2); } }