private static object GetScalar(string fieldName, string tableAlias, CSAggregate aggregate, CSFilter queryFilter, string orderBy) { CSSchema schema = CSSchema.Get(typeof(T)); if (tableAlias == null) { tableAlias = CSNameGenerator.NextTableAlias; } if (orderBy == null) { orderBy = ""; } string aggregateExpr = null; int maxRows = 0; switch (aggregate) { case CSAggregate.None: aggregateExpr = "{0}"; maxRows = 1; break; case CSAggregate.Sum: aggregateExpr = "sum({0})"; break; case CSAggregate.SumDistinct: aggregateExpr = "sum(distinct {0})"; break; case CSAggregate.Count: aggregateExpr = "count(*)"; break; case CSAggregate.CountDistinct: aggregateExpr = "count(distinct {0})"; break; case CSAggregate.Avg: aggregateExpr = "avg({0})"; break; case CSAggregate.AvgDistinct: aggregateExpr = "avg(distinct {0})"; break; case CSAggregate.Max: aggregateExpr = "max({0})"; break; case CSAggregate.Min: aggregateExpr = "min({0})"; break; } CSJoinList joins = new CSJoinList(); if (fieldName != "*") { fieldName = CSExpressionParser.ParseFilter(fieldName, schema, tableAlias, joins); } string whereFilter = CSExpressionParser.ParseFilter(queryFilter.Expression, schema, tableAlias, joins); orderBy = CSExpressionParser.ParseOrderBy(orderBy, schema, tableAlias, joins); string sqlQuery = schema.DB.BuildSelectSQL(schema.TableName, tableAlias, new[] { String.Format(aggregateExpr, fieldName) }, null, joins.BuildJoinExpressions(), whereFilter, orderBy, 1, maxRows, false, false); return(schema.DB.GetScalar(sqlQuery, queryFilter.Parameters)); }
private void Populate() { if (Populated) { return; } if (Relation != null && RelationObject != null && Relation.RelationType == CSSchemaRelationType.OneToMany && RelationObject.IsNew) { _objectArray = new List <TObjectType>(); Populated = true; return; } CSTable table = new CSTable(Schema); //string mainAlias = CSHelper.NextTableAlias; List <string> columnList = new List <string>(Schema.ColumnsToRead.Count); List <string> aliasList = new List <string>(Schema.ColumnsToRead.Count); Dictionary <string, string> aliasMap = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); foreach (string columnName in Schema.ColumnsToRead) { string alias = CSNameGenerator.NextFieldAlias; columnList.Add(table.TableAlias + "." + columnName); aliasList.Add(alias); aliasMap.Add(alias, columnName); } CSJoinList filterJoins = new CSJoinList(); List <PrefetchField> prefetchFields = CSObject.GetPrefetchFieldsOne(table, columnList, aliasList, filterJoins, PrefetchPaths); CSFilter whereFilter; if (PrefetchFilter != null) { whereFilter = new CSFilter(DB.QuoteField(table.TableAlias + "." + PrefetchFilter.ForeignKey) + " in (" + PrefetchFilter.InStatement + ")", PrefetchFilter.Parameters); } else { string parsedFilterExpression = CSExpressionParser.ParseFilter(Filter.Expression, Schema, table.TableAlias, filterJoins); whereFilter = new CSFilter(parsedFilterExpression, Filter.Parameters); CSFilter relationFilter = BuildRelationFilter(table.TableAlias); whereFilter = whereFilter.And(CSExpressionParser.ParseFilter(relationFilter.Expression, Schema, table.TableAlias, filterJoins), relationFilter.Parameters); } string parsedOrderBy = CSExpressionParser.ParseOrderBy(OrderBy, Schema, table.TableAlias, filterJoins); string sqlQuery = DB.BuildSelectSQL(table.TableName, table.TableAlias, columnList.ToArray(), aliasList.ToArray(), filterJoins.BuildJoinExpressions(), whereFilter.Expression, parsedOrderBy, StartRecord, MaxRecords, true, false); _objectArray = GetObjects(sqlQuery, whereFilter.Parameters, aliasMap, prefetchFields); if (Schema.KeyColumns.Count == 1) { string columnName = Schema.KeyColumns[0].Name; _objectMap = new Dictionary <object, TObjectType>(); foreach (TObjectType csObject in _objectArray) { _objectMap.Add(csObject.Data["#" + columnName].Value, csObject); } } foreach (CSSchemaField prefetchField in GetPrefetchFieldsMany()) { CSRelation relation = prefetchField.Relation; Dictionary <object, TObjectType> prefetchMap = new Dictionary <object, TObjectType>(); // Creates empty lists in each object of this list foreach (TObjectType csObject in _objectArray) { prefetchMap[csObject.Data["#" + relation.LocalKey].Value] = csObject; CSList relationCollection = (CSList)Activator.CreateInstance(prefetchField.FieldType); relationCollection.Relation = relation; relationCollection.RelationObject = csObject; relationCollection.InitializePrefetch(); csObject.Data[prefetchField.Name].ValueDirect = relationCollection; csObject.Data[prefetchField.Name].ValueState = CSFieldValueState.Read; } Type objectType = relation.ForeignSchema.ClassType; CSList csList = (CSList)Activator.CreateInstance(typeof(CSList <>).MakeGenericType(objectType)); //string prefetchTableAlias = CSNameGenerator.NextTableAlias; string prefetchFilter = DB.BuildSelectSQL(table.TableName, table.TableAlias, new[] { table.TableAlias + "." + relation.LocalKey }, new[] { CSNameGenerator.NextFieldAlias }, filterJoins.BuildJoinExpressions(), whereFilter.Expression, parsedOrderBy, StartRecord, MaxRecords, true, true); csList.PrefetchFilter = new PrefetchFilter(relation.ForeignKey, prefetchFilter, whereFilter.Parameters); if (PrefetchPaths != null && PrefetchPaths.Length > 0) { List <string> newPrefetchPaths = new List <string>(); foreach (string path in PrefetchPaths) { if (path.StartsWith(prefetchField.Name + ".")) { newPrefetchPaths.Add(path.Substring(prefetchField.Name.Length + 1)); } } if (newPrefetchPaths.Count > 0) { csList.PrefetchPaths = newPrefetchPaths.ToArray(); } } foreach (CSObject csObject in csList) { object localKey = csObject.Data["#" + relation.ForeignKey].ValueDirect; CSList relationCollection = (CSList)prefetchMap[localKey].Data[prefetchField.Name].ValueDirect; relationCollection.AddFromPrefetch(csObject); } } Populated = true; }
internal static string Parse(CSSchema schema, string input, string tableAlias, CSJoinList joins) { if (input == "") { return(input); } List <Token> tokens = PreParse(input); QueryExpression rootQuery = new QueryExpression(schema, tableAlias); rootQuery.Joins = joins; QueryExpression finalQuery = Parse(rootQuery, tokens, 0, tokens.Count); return(finalQuery.Expression); }
internal static string ParseOrderBy(string expression, CSSchema schema, string tableAlias, CSJoinList joinList) { //joinList = new CSJoinList(); if (expression.Trim().Length < 1) { return(expression); } string parsedExpression = ""; string[] terms = expression.Split(','); foreach (string term in terms) { if (term.Length < 1) { continue; } bool ascending = true; string fieldName = term; if (term.EndsWith("-")) { ascending = false; } if (term.EndsWith("+") || term.EndsWith("-")) { fieldName = term.Substring(0, term.Length - 1); } if (parsedExpression.Length > 1) { parsedExpression += ","; } parsedExpression += ParseFilter(fieldName, schema, tableAlias, joinList); if (!ascending) { parsedExpression += " DESC"; } } return(parsedExpression); }
internal static string ParseFilter(string expressionText, CSSchema schema, string tableAlias, CSJoinList joins) { return(Parse(schema, expressionText, tableAlias, joins)); }
internal static List <PrefetchField> GetPrefetchFieldsOne(CSTable table, List <string> fieldList, List <string> aliasList, CSJoinList joinList, string[] prefetchPaths) { List <PrefetchField> prefetchFields = new List <PrefetchField>(); foreach (CSSchemaField schemaField in table.Schema.Fields) { bool prefetch = schemaField.Prefetch; string fieldName = schemaField.Name; prefetch |= (prefetchPaths != null && prefetchPaths.Any(s => { if (s.IndexOf('.') > 0) { s = s.Substring(0, s.IndexOf('.')); } return(s == fieldName); })); if (schemaField.Relation != null && schemaField.Relation.RelationType == CSSchemaRelationType.ManyToOne && prefetch) { CSJoin join = new CSJoin(schemaField.Relation, table.TableAlias); joinList.Add(join); PrefetchField prefetchField = new PrefetchField(); prefetchField.SchemaField = schemaField; foreach (string columnName in schemaField.Relation.ForeignSchema.ColumnsToRead) { string alias = CSNameGenerator.NextFieldAlias; fieldList.Add(join.RightAlias + "." + columnName); aliasList.Add(alias); prefetchField.AliasMap[alias] = columnName; } prefetchFields.Add(prefetchField); } } return(prefetchFields); }
internal bool ReadFields(CSStringCollection columnList, CSStringCollection keyList, List <object> valueList) { List <string> fieldList = new List <string>(); List <string> aliasList = new List <string>(); Dictionary <string, string> fieldAliasMap = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); CSFilter whereClause = new CSFilter(); CSTable table = new CSTable(_schema); CSParameterCollection parameters = new CSParameterCollection(); foreach (CSSchemaColumn schemaColumn in _schema.Columns) { if (keyList.Contains(schemaColumn.Name)) { CSParameter parameter = parameters.Add(); parameter.Value = valueList[keyList.IndexOf(schemaColumn.Name)]; whereClause = whereClause.And(table.TableAlias + "." + _schema.DB.QuoteField(schemaColumn.Name) + "=" + parameter.Name); _fieldData["#" + schemaColumn.Name].ValueDirect = parameter.Value; _fieldData["#" + schemaColumn.Name].ValueState = CSFieldValueState.Read; } else if (columnList.Contains(schemaColumn.Name)) { string alias = CSNameGenerator.NextFieldAlias; fieldList.Add(table.TableAlias + "." + schemaColumn.Name); aliasList.Add(alias); fieldAliasMap[alias] = schemaColumn.Name; } } /** Build query for prefetch of relations **/ CSJoinList joinList = new CSJoinList(); List <PrefetchField> prefetchFields = GetPrefetchFieldsOne(table, fieldList, aliasList, joinList, null); if (whereClause.Expression.Length == 0) { return(false); } if (fieldList.Count == 0) { return(true); } string sqlQuery = _schema.DB.BuildSelectSQL(table.TableName, table.TableAlias, fieldList.ToArray(), aliasList.ToArray(), joinList.BuildJoinExpressions(), whereClause.Expression, null, 1, 1, true, false); using (CSTransaction csTransaction = new CSTransaction(_schema)) { using (ICSDbReader dataReader = _schema.DB.CreateReader(sqlQuery, parameters)) { if (!dataReader.Read()) { return(false); } FromDataReader(dataReader, fieldAliasMap); foreach (PrefetchField prefetchField in prefetchFields) { ReadRelationToOne(prefetchField.SchemaField, dataReader, prefetchField.AliasMap); } } csTransaction.Commit(); } return(true); }