public override JoinQueryResult Visit(RootQueryExpression exp) { Type type = exp.ElementType; TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(type); string explicitTableName = exp.ExplicitTable; DbTable dbTable = typeDescriptor.Table; if (explicitTableName != null) { dbTable = new DbTable(explicitTableName, dbTable.Schema); } string alias = this._queryModel.GenerateUniqueTableAlias(dbTable.Name); DbTableSegment tableSeg = CreateTableSegment(dbTable, alias, exp.Lock); DbTable aliasTable = new DbTable(alias); ComplexObjectModel model = typeDescriptor.GenObjectModel(aliasTable); //TODO 解析 on 条件表达式 var scopeParameters = this._scopeParameters.Clone(this._conditionExpression.Parameters.Last(), model); DbExpression condition = GeneralExpressionParser.Parse(this._conditionExpression, scopeParameters, this._queryModel.ScopeTables); DbJoinTableExpression joinTable = new DbJoinTableExpression(this._joinType.AsDbJoinType(), tableSeg, condition); JoinQueryResult result = new JoinQueryResult(); result.ResultModel = model; result.JoinTable = joinTable; return(result); }
ComplexObjectModel GenComplexObjectModel(ComplexPropertyDescriptor navigationDescriptor, NavigationNode navigationNode, QueryModel queryModel) { TypeDescriptor navigationTypeDescriptor = EntityTypeContainer.GetDescriptor(navigationDescriptor.PropertyType); DbTable dbTable = navigationTypeDescriptor.Table; DbTableExpression tableExp = new DbTableExpression(dbTable); string alias = queryModel.GenerateUniqueTableAlias(dbTable.Name); DbTableSegment joinTableSeg = new DbTableSegment(tableExp, alias, queryModel.FromTable.Table.Lock); DbTable aliasTable = new DbTable(alias); ComplexObjectModel navigationObjectModel = navigationTypeDescriptor.GenObjectModel(aliasTable); navigationObjectModel.NullChecking = navigationObjectModel.PrimaryKey; PrimitivePropertyDescriptor foreignKeyPropertyDescriptor = navigationDescriptor.ForeignKeyProperty; DbExpression foreignKeyColumn = this.GetPrimitiveMember(foreignKeyPropertyDescriptor.Property); DbExpression joinCondition = DbExpression.Equal(foreignKeyColumn, navigationObjectModel.PrimaryKey); DbJoinTableExpression joinTableExp = new DbJoinTableExpression(foreignKeyPropertyDescriptor.IsNullable ? DbJoinType.LeftJoin : DbJoinType.InnerJoin, joinTableSeg, joinCondition); this.DependentTable.JoinTables.Add(joinTableExp); navigationObjectModel.DependentTable = joinTableExp; DbExpression condition = this.ParseCondition(navigationNode.Condition, navigationObjectModel, queryModel.ScopeTables); //AndWhere的条件放到join条件里去 joinTableExp.AppendCondition(condition); navigationObjectModel.Filter = this.ParseCondition(navigationNode.Filter, navigationObjectModel, queryModel.ScopeTables); //queryModel.Filters.Add(navigationObjectModel.Filter); return(navigationObjectModel); }
ComplexObjectModel GenCollectionElementObjectModel(TypeDescriptor elementTypeDescriptor, NavigationNode navigationNode, QueryModel queryModel) { DbTable dbTable = elementTypeDescriptor.Table; DbTableExpression tableExp = new DbTableExpression(dbTable); string alias = queryModel.GenerateUniqueTableAlias(dbTable.Name); DbTableSegment joinTableSeg = new DbTableSegment(tableExp, alias, queryModel.FromTable.Table.Lock); DbTable aliasTable = new DbTable(alias); ComplexObjectModel elementObjectModel = elementTypeDescriptor.GenObjectModel(aliasTable); elementObjectModel.NullChecking = elementObjectModel.PrimaryKey; ComplexPropertyDescriptor navigationDescriptor = elementTypeDescriptor.ComplexPropertyDescriptors.Where(a => a.PropertyType == this.ObjectType).FirstOrDefault(); if (navigationDescriptor == null) { throw new ChloeException($"You have to define a navigation property which type is '{this.ObjectType.FullName}' on class '{elementTypeDescriptor.Definition.Type.FullName}'."); } DbExpression elementForeignKeyColumn = elementObjectModel.GetPrimitiveMember(navigationDescriptor.ForeignKeyProperty.Property); DbExpression joinCondition = DbExpression.Equal(this.PrimaryKey, elementForeignKeyColumn); DbJoinTableExpression joinTableExp = new DbJoinTableExpression(DbJoinType.LeftJoin, joinTableSeg, joinCondition); this.DependentTable.JoinTables.Add(joinTableExp); elementObjectModel.DependentTable = joinTableExp; var condition = this.ParseCondition(navigationNode.Condition, elementObjectModel, queryModel.ScopeTables); //AndWhere的条件放到join条件里去 joinTableExp.AppendCondition(condition); elementObjectModel.Filter = this.ParseCondition(navigationNode.Filter, elementObjectModel, queryModel.ScopeTables); bool orderByPrimaryKeyExists = queryModel.Orderings.Where(a => a.Expression == this.PrimaryKey).Any(); if (!orderByPrimaryKeyExists) { //结果集分组 DbOrdering ordering = new DbOrdering(this.PrimaryKey, DbOrderType.Asc); queryModel.Orderings.Add(ordering); } //queryModel.Filters.Add(elementObjectModel.Filter); return(elementObjectModel); }
static QueryModel CreateQueryModel(RootQueryExpression rootQueryExp, ScopeParameterDictionary scopeParameters, StringSet scopeTables, Func <string, string> tableAliasGenerator) { Type entityType = rootQueryExp.ElementType; if (entityType.IsAbstract || entityType.IsInterface) { throw new ArgumentException("The type of input can not be abstract class or interface."); } QueryModel queryModel = new QueryModel(scopeParameters, scopeTables); TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(entityType); DbTable dbTable = typeDescriptor.GenDbTable(rootQueryExp.ExplicitTable); string alias = null; if (tableAliasGenerator != null) { alias = tableAliasGenerator(dbTable.Name); } else { alias = queryModel.GenerateUniqueTableAlias(dbTable.Name); } queryModel.FromTable = CreateRootTable(dbTable, alias, rootQueryExp.Lock); DbTable aliasTable = new DbTable(alias); ComplexObjectModel model = typeDescriptor.GenObjectModel(aliasTable); model.DependentTable = queryModel.FromTable; queryModel.ResultModel = model; ParseFilters(queryModel, typeDescriptor.Definition.Filters, rootQueryExp.ContextFilters); return(queryModel); }
static QueryModel CreateQueryModel(Type type, string explicitTableName, LockType lockType, ScopeParameterDictionary scopeParameters, StringSet scopeTables) { if (type.IsAbstract || type.IsInterface) throw new ArgumentException("The type of input can not be abstract class or interface."); QueryModel queryModel = new QueryModel(scopeParameters, scopeTables); TypeDescriptor typeDescriptor = EntityTypeContainer.GetDescriptor(type); DbTable dbTable = typeDescriptor.Table; if (explicitTableName != null) dbTable = new DbTable(explicitTableName, dbTable.Schema); string alias = queryModel.GenerateUniqueTableAlias(dbTable.Name); queryModel.FromTable = CreateRootTable(dbTable, alias, lockType); DbTable aliasTable = new DbTable(alias); ComplexObjectModel model = typeDescriptor.GenObjectModel(aliasTable); model.DependentTable = queryModel.FromTable; queryModel.ResultModel = model; return queryModel; }