예제 #1
0
        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);
        }
예제 #2
0
        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;
        }
예제 #3
0
        private static object EvalVariable(string var, QueryExpression parentQuery)
        {
            Match match = _regexVar.Match(var);

            if (!match.Success)
            {
                throw new CSExpressionException("Object [" + var + "] is unknown");
            }

            List <string> fieldNames = new List <string>();

            foreach (Capture capture in match.Groups["Object"].Captures)
            {
                fieldNames.Add(capture.Value);
            }

            QueryExpression subExpression = null;

            CSTable currentTable = parentQuery.Table;

            string fieldName = null;

            for (int i = 0; i < fieldNames.Count; i++)
            {
                bool isLast = (i == fieldNames.Count - 1);

                CSJoin        currentJoin = null;
                CSSchemaField schemaField = currentTable.Schema.Fields[fieldNames[i]];

                if (schemaField == null)
                {
                    throw new CSException("Error in expression. [" + fieldNames[i] + "] is not a valid field name");
                }

                if (schemaField.Relation != null)
                {
                    switch (schemaField.Relation.RelationType)
                    {
                    case CSSchemaRelationType.OneToMany:
                    {
                        if (subExpression != null)
                        {
                            throw new CSExpressionException("Error in expression [" + var + "]: Multiple *ToMany relations");
                        }

                        subExpression       = new QueryExpression(schemaField.Relation.ForeignSchema);
                        subExpression.Joins = new CSJoinList();

                        subExpression.Expression = currentTable.TableAlias + "." + currentTable.Schema.DB.QuoteField(schemaField.Relation.LocalKey) + "=" + subExpression.Table.TableAlias + "." + currentTable.Schema.DB.QuoteField(schemaField.Relation.ForeignKey);
                    }
                    break;

                    case CSSchemaRelationType.ManyToMany:
                    {
                        if (subExpression != null)
                        {
                            throw new CSExpressionException("Error in expression [" + var + "]: Multiple *ToMany relations");
                        }

                        subExpression       = new QueryExpression(schemaField.Relation.ForeignSchema);
                        subExpression.Joins = new CSJoinList();

                        currentJoin = new CSJoin();

                        currentJoin.LeftSchema  = schemaField.Relation.ForeignSchema;
                        currentJoin.LeftTable   = subExpression.Table.TableName;
                        currentJoin.LeftAlias   = subExpression.Table.TableAlias;
                        currentJoin.RightTable  = schemaField.Relation.LinkTable;
                        currentJoin.RightAlias  = CSNameGenerator.NextTableAlias;
                        currentJoin.LeftColumn  = schemaField.Relation.ForeignKey;
                        currentJoin.RightColumn = schemaField.Relation.ForeignLinkKey;

                        currentJoin.Type = CSJoinType.Inner;

                        subExpression.Joins.Add(currentJoin);

                        subExpression.Expression = currentJoin.RightAlias + "." + currentTable.Schema.DB.QuoteField(schemaField.Relation.LocalLinkKey) + "=" + currentTable.TableAlias + "." + currentTable.Schema.DB.QuoteField(schemaField.Relation.LocalKey);

                        currentJoin = null;
                    }
                    break;

                    case CSSchemaRelationType.ManyToOne:
                    {
                        if (!isLast)
                        {
                            if (subExpression != null)                                             // meaning we already encountered a *toMany relation
                            {
                                currentJoin = new CSJoin(schemaField.Relation, subExpression.Table.TableAlias);

                                if (subExpression.Joins.Contains(currentJoin))
                                {
                                    currentJoin = subExpression.Joins.GetExistingJoin(currentJoin);
                                }
                                else
                                {
                                    subExpression.Joins.Add(currentJoin);
                                }
                            }
                            else
                            {
                                currentJoin = new CSJoin(schemaField.Relation, currentTable.TableAlias);

                                if (parentQuery.Joins.Contains(currentJoin))
                                {
                                    currentJoin = parentQuery.Joins.GetExistingJoin(currentJoin);
                                }
                                else
                                {
                                    parentQuery.Joins.Add(currentJoin);
                                }
                            }
                        }
                    }
                    break;
                    }

                    if (!isLast)
                    {
                        if (currentJoin != null)
                        {
                            currentTable = new CSTable(schemaField.Relation.ForeignSchema, currentJoin.RightAlias);
                        }
                        else
                        {
                            if (subExpression != null)
                            {
                                currentTable = new CSTable(schemaField.Relation.ForeignSchema, subExpression.Table.TableAlias);
                            }
                            else
                            {
                                currentTable = new CSTable(schemaField.Relation.ForeignSchema);
                            }
                        }
                    }
                    else
                    {
                        fieldName = currentTable.Schema.DB.QuoteField(currentTable.TableAlias + "." + schemaField.Relation.LocalKey);
                    }
                }
                else
                {
                    fieldName = currentTable.Schema.DB.QuoteField(currentTable.TableAlias + "." + schemaField.MappedColumn.Name);
                }
            }

            if (subExpression != null)
            {
                subExpression.FieldName = fieldName;

                return(subExpression);
            }
            else
            {
                //if (fieldName != null)
                return(fieldName);
            }
        }
예제 #4
0
 public QueryExpression(CSSchema schema)
 {
     Table = new CSTable(schema);
 }
예제 #5
0
 public QueryExpression(CSSchema schema, string tableAlias)
 {
     Table = new CSTable(schema, tableAlias);
 }
예제 #6
0
        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);
        }
예제 #7
0
		private static object EvalVariable(string var, QueryExpression parentQuery)
		{
			Match match = _regexVar.Match(var);

			if (!match.Success)
				throw new CSExpressionException("Object [" + var + "] is unknown");

			List<string> fieldNames = new List<string>();

			foreach (Capture capture in match.Groups["Object"].Captures)
				fieldNames.Add(capture.Value);

			QueryExpression subExpression = null;
		    
			CSTable currentTable = parentQuery.Table;

			string fieldName = null;

			for (int i = 0; i < fieldNames.Count; i++)
			{
				bool isLast = (i == fieldNames.Count - 1);

				CSJoin currentJoin = null;
				CSSchemaField schemaField = currentTable.Schema.Fields[fieldNames[i]];

				if (schemaField == null)
					throw new CSException("Error in expression. [" + fieldNames[i] + "] is not a valid field name");

				if (schemaField.Relation != null)
				{
					switch (schemaField.Relation.RelationType)
					{
						case CSSchemaRelationType.OneToMany:
							{
								if (subExpression != null)
									throw new CSExpressionException("Error in expression [" + var + "]: Multiple *ToMany relations");

								subExpression = new QueryExpression(schemaField.Relation.ForeignSchema);
								subExpression.Joins = new CSJoinList();

								subExpression.Expression = currentTable.TableAlias + "." + currentTable.Schema.DB.QuoteField(schemaField.Relation.LocalKey) + "=" + subExpression.Table.TableAlias + "." + currentTable.Schema.DB.QuoteField(schemaField.Relation.ForeignKey);
							}
							break;

						case CSSchemaRelationType.ManyToMany:
							{
								if (subExpression != null)
									throw new CSExpressionException("Error in expression [" + var + "]: Multiple *ToMany relations");

								subExpression = new QueryExpression(schemaField.Relation.ForeignSchema);
								subExpression.Joins = new CSJoinList();

								currentJoin = new CSJoin();

								currentJoin.LeftSchema = schemaField.Relation.ForeignSchema;
								currentJoin.LeftTable = subExpression.Table.TableName;
								currentJoin.LeftAlias = subExpression.Table.TableAlias;
								currentJoin.RightTable = schemaField.Relation.LinkTable;
								currentJoin.RightAlias = CSNameGenerator.NextTableAlias;
								currentJoin.LeftColumn = schemaField.Relation.ForeignKey;
								currentJoin.RightColumn = schemaField.Relation.ForeignLinkKey;

								currentJoin.Type = CSJoinType.Inner;

								subExpression.Joins.Add(currentJoin);

								subExpression.Expression = currentJoin.RightAlias + "." + currentTable.Schema.DB.QuoteField(schemaField.Relation.LocalLinkKey) + "=" + currentTable.TableAlias + "." + currentTable.Schema.DB.QuoteField(schemaField.Relation.LocalKey);

								currentJoin = null;
							}
							break;

						case CSSchemaRelationType.ManyToOne:
							{
								if (!isLast)
								{
									if (subExpression != null) // meaning we already encountered a *toMany relation
									{
										currentJoin = new CSJoin(schemaField.Relation, subExpression.Table.TableAlias);

										if (subExpression.Joins.Contains(currentJoin))
											currentJoin = subExpression.Joins.GetExistingJoin(currentJoin);
										else
											subExpression.Joins.Add(currentJoin);
									}
									else
									{
										currentJoin = new CSJoin(schemaField.Relation, currentTable.TableAlias);

										if (parentQuery.Joins.Contains(currentJoin))
											currentJoin = parentQuery.Joins.GetExistingJoin(currentJoin);
										else
											parentQuery.Joins.Add(currentJoin);
									}
								}
							}
							break;
					}

					if (!isLast)
					{
						if (currentJoin != null)
							currentTable = new CSTable(schemaField.Relation.ForeignSchema, currentJoin.RightAlias);
						else
						{
							if (subExpression != null)
								currentTable = new CSTable(schemaField.Relation.ForeignSchema, subExpression.Table.TableAlias);
							else
								currentTable = new CSTable(schemaField.Relation.ForeignSchema);

						}
					}
					else
					{
						fieldName = currentTable.Schema.DB.QuoteField(currentTable.TableAlias + "." + schemaField.Relation.LocalKey);
					}
				}
				else
				{
					fieldName = currentTable.Schema.DB.QuoteField(currentTable.TableAlias + "." + schemaField.MappedColumn.Name);
				}
			}

			if (subExpression != null)
			{
			    subExpression.FieldName = fieldName;

                return subExpression;
			}
			else
			{
				//if (fieldName != null)
					return fieldName;
			}

			
		}
예제 #8
0
			public QueryExpression(CSSchema schema)
			{
				Table = new CSTable(schema);
			}
예제 #9
0
			public QueryExpression(CSSchema schema, string tableAlias)
			{
				Table = new CSTable(schema, tableAlias);
			}