private IList ExecuteSubQuery(Type t, QueryContextsEntry queryContextsEntry) { IQueryGenerator queryGenerator = ConfigContainer.Resolve <IQueryGenerator>(); bool hasBeenPrepared = PrepareParameters(); string generatedQuery; if (this.queryLanguage == QueryLanguage.NDOql) { generatedQuery = queryGenerator.GenerateQueryString(queryContextsEntry, this.expressionTree, this.hollowResults, this.queryContextsForTypes.Count > 1, this.orderings, this.skip, this.take); } else { generatedQuery = (string)this.expressionTree.Value; } if (hasBeenPrepared) { WriteBackParameters(); } using (IPersistenceHandler persistenceHandler = this.pm.PersistenceHandlerManager.GetPersistenceHandler(t)) { persistenceHandler.VerboseMode = this.pm.VerboseMode; persistenceHandler.LogAdapter = this.pm.LogAdapter; this.pm.CheckTransaction(persistenceHandler, t); DataTable table = persistenceHandler.PerformQuery(generatedQuery, this.parameters, this.pm.DataSet); return(pm.DataTableToIList(t, table.Rows, this.hollowResults)); } }
private object ExecuteAggregateQuery(QueryContextsEntry queryContextsEntry, string field, AggregateType aggregateType) { Type t = queryContextsEntry.Type; IQueryGenerator queryGenerator = ConfigContainer.Resolve <IQueryGenerator>(); string generatedQuery = queryGenerator.GenerateAggregateQueryString(field, queryContextsEntry, this.expressionTree, this.queryContextsForTypes.Count > 1, aggregateType); using (IPersistenceHandler persistenceHandler = this.pm.PersistenceHandlerManager.GetPersistenceHandler(t)) { persistenceHandler.VerboseMode = this.pm.VerboseMode; persistenceHandler.LogAdapter = this.pm.LogAdapter; this.pm.CheckTransaction(persistenceHandler, t); // Note, that we can't execute all subQueries in one batch, because // the subqueries could be executed against different connections. // TODO: This could be optimized, if we made clear whether the involved tables // can be reached with the same connection. var l = persistenceHandler.ExecuteBatch(new string[] { generatedQuery }, this.parameters); if (l.Count == 0) { return(null); } return((l[0])["AggrResult"]); } }
/// <summary> /// Constructs the subqueries necessary to fetch all objects of a /// class and its subclasses. /// </summary> /// <remarks> /// The function isn't actually recursive. The subclasses have been /// recursively collected in NDOMapping. /// </remarks> private void CreateQueryContextsForTypes() { Dictionary <string, Type> usedTables = new Dictionary <string, Type>(); if (!resultType.IsAbstract) { Class cl = pm.GetClass(this.resultType); usedTables.Add(cl.TableName, cl.SystemType); } if (this.allowSubclasses) { // Check if subclasses are mapped to the same table. // Always fetch for the base class in the table foreach (Class cl in pm.GetClass(resultType).Subclasses) { string tn = cl.TableName; if (usedTables.ContainsKey(tn)) { Type t = (Type)usedTables[tn]; if (t.IsSubclassOf(cl.SystemType)) { usedTables.Remove(tn); usedTables.Add(tn, cl.SystemType); } break; } usedTables.Add(tn, cl.SystemType); } } var contextGenerator = ConfigContainer.Resolve <RelationContextGenerator>(null, new ParameterOverride(this.pm.mappings)); this.queryContextsForTypes = new List <QueryContextsEntry>(); // usedTables now contains all assignable classes of our result type foreach (var de in usedTables) { Type t2 = (Type)de.Value; // Now we have to iterate through all mutations of // polymorphic relations, used in the filter expression var queryContexts = contextGenerator.GetContexts(this.pm.GetClass(t2), this.expressionTree); this.queryContextsForTypes.Add(new QueryContextsEntry() { Type = t2, QueryContexts = queryContexts }); } }
private List <ObjectRowPair <T> > ExecuteOrderedSubQuery(QueryContextsEntry queryContextsEntry) { Type t = queryContextsEntry.Type; Class resultSubClass = this.pm.GetClass(t); DataTable comparismTable = new DataTable("ComparismTable"); foreach (QueryOrder order in this.orderings) { DataColumn col = comparismTable.Columns.Add(order.FieldName); if (order.IsAscending) { col.AutoIncrementStep = 1; } else { col.AutoIncrementStep = -1; } } DataTable table = null; using (IPersistenceHandler persistenceHandler = this.pm.PersistenceHandlerManager.GetPersistenceHandler(t)) { persistenceHandler.VerboseMode = this.pm.VerboseMode; persistenceHandler.LogAdapter = this.pm.LogAdapter; this.pm.CheckTransaction(persistenceHandler, t); bool hasBeenPrepared = PrepareParameters(); IQueryGenerator queryGenerator = ConfigContainer.Resolve <IQueryGenerator>(); string generatedQuery = queryGenerator.GenerateQueryString(queryContextsEntry, this.expressionTree, this.hollowResults, this.queryContextsForTypes.Count > 1, this.orderings, this.skip, this.take); if (hasBeenPrepared) { WriteBackParameters(); } table = persistenceHandler.PerformQuery(generatedQuery, this.parameters, this.pm.DataSet); } DataRow[] rows = table.Select(); var objects = pm.DataTableToIList(t, rows, this.hollowResults); List <ObjectRowPair <T> > result = new List <ObjectRowPair <T> >(objects.Count); int i = 0; IProvider provider = mappings.GetProvider(t); foreach (T obj in objects) { DataRow row = rows[i++]; DataRow newRow = comparismTable.NewRow(); foreach (QueryOrder order in this.orderings) { string newColumnName = order.FieldName; if (!comparismTable.Columns.Contains(newColumnName)) { throw new InternalException(558, "Query.cs - Column not found."); } string oldColumnName = resultSubClass.FindField(order.FieldName).Column.Name; if (!table.Columns.Contains(oldColumnName)) { throw new InternalException(561, "Query.cs - Column not found."); } newRow[newColumnName] = row[oldColumnName]; } result.Add(new ObjectRowPair <T>(obj, newRow)); } return(result); }