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); }
DbExpression ParseCondition(LambdaExpression condition, ComplexObjectModel objectModel, StringSet scopeTables) { if (condition == null) { return(null); } return(FilterPredicateParser.Parse(condition, new ScopeParameterDictionary(1) { { condition.Parameters[0], objectModel } }, scopeTables)); }
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); }
public ComplexObjectModel GetComplexMember(MemberInfo memberInfo) { memberInfo = memberInfo.AsReflectedMemberOf(this.ObjectType); ComplexObjectModel ret = null; if (!this.ComplexMembers.TryGetValue(memberInfo, out ret)) { //从构造函数中查 ParameterInfo p = null; if (!this.ConstructorDescriptor.MemberParameterMap.TryGetValue(memberInfo, out p)) { return(null); } if (!this.ComplexConstructorParameters.TryGetValue(p, out ret)) { return(null); } } return(ret as ComplexObjectModel); }
protected override IObjectModel VisitNew(NewExpression exp) { IObjectModel result = new ComplexObjectModel(exp.Constructor); ParameterInfo[] parames = exp.Constructor.GetParameters(); for (int i = 0; i < parames.Length; i++) { ParameterInfo pi = parames[i]; Expression argExp = exp.Arguments[i]; if (MappingTypeSystem.IsMappingType(pi.ParameterType)) { DbExpression dbExpression = this.ResolveExpression(argExp); result.AddConstructorParameter(pi, dbExpression); } else { IObjectModel subResult = this.Visit(argExp); result.AddConstructorParameter(pi, (ComplexObjectModel)subResult); } } return(result); }
public CollectionObjectModel(Type ownerType, PropertyInfo associatedProperty, ComplexObjectModel elementModel) : base(associatedProperty.PropertyType) { this.OwnerType = ownerType; this.AssociatedProperty = associatedProperty; this._collectionType = associatedProperty.PropertyType; this.ElementModel = elementModel; }
public virtual void AddComplexMember(MemberInfo p, ComplexObjectModel model) { throw new NotSupportedException(); }
public virtual void AddConstructorParameter(ParameterInfo p, ComplexObjectModel complexModel) { throw new NotSupportedException(); }
public void Include(NavigationNode navigationNode, QueryModel queryModel, bool handleCollection) { TypeDescriptor descriptor = EntityTypeContainer.GetDescriptor(this.ObjectType); PropertyDescriptor navigationDescriptor = descriptor.GetPropertyDescriptor(navigationNode.Property); if (navigationDescriptor.Definition.Kind == TypeKind.Primitive) { throw new NotSupportedException($"'{navigationNode.Property.Name}' is not navigation property."); } ComplexObjectModel objectModel = null; if (navigationDescriptor.Definition.Kind == TypeKind.Complex) { objectModel = this.GetComplexMember(navigationNode.Property); if (objectModel == null) { objectModel = this.GenComplexObjectModel(navigationDescriptor as ComplexPropertyDescriptor, navigationNode, queryModel); this.AddComplexMember(navigationNode.Property, objectModel); } else { DbExpression condition = this.ParseCondition(navigationNode.Condition, objectModel, queryModel.ScopeTables); var joinTable = objectModel.DependentTable as DbJoinTableExpression; joinTable.AppendCondition(condition); } } else { if (!handleCollection) { this.IncludeCollections.Add(navigationNode); return; } CollectionObjectModel collectionModel = this.GetCollectionMember(navigationNode.Property); if (collectionModel == null) { Type collectionType = navigationDescriptor.PropertyType; TypeDescriptor elementTypeDescriptor = EntityTypeContainer.GetDescriptor(collectionType.GetGenericArguments()[0]); ComplexObjectModel elementModel = this.GenCollectionElementObjectModel(elementTypeDescriptor, navigationNode, queryModel); collectionModel = new CollectionObjectModel(this.ObjectType, navigationNode.Property, elementModel); this.AddCollectionMember(navigationNode.Property, collectionModel); } else { DbExpression condition = this.ParseCondition(navigationNode.Condition, collectionModel.ElementModel, queryModel.ScopeTables); var joinTable = collectionModel.ElementModel.DependentTable as DbJoinTableExpression; joinTable.AppendCondition(condition); } objectModel = collectionModel.ElementModel; } if (navigationNode.Next != null) { objectModel.Include(navigationNode.Next, queryModel, handleCollection); } }
public IObjectModel ToNewObjectModel(DbSqlQueryExpression sqlQuery, DbTable table, DbMainTableExpression dependentTable) { ComplexObjectModel newModel = new ComplexObjectModel(this.ConstructorDescriptor); newModel.DependentTable = dependentTable; newModel.IncludeCollections.AddRange(this.IncludeCollections); foreach (var kv in this.PrimitiveConstructorParameters) { ParameterInfo pi = kv.Key; DbExpression exp = kv.Value; DbColumnAccessExpression cae = null; cae = ObjectModelHelper.ParseColumnAccessExpression(sqlQuery, table, exp, pi.Name); newModel.AddConstructorParameter(pi, cae); } foreach (var kv in this.ComplexConstructorParameters) { ParameterInfo pi = kv.Key; IObjectModel val = kv.Value; ComplexObjectModel complexMemberModel = val.ToNewObjectModel(sqlQuery, table, dependentTable) as ComplexObjectModel; newModel.AddConstructorParameter(pi, complexMemberModel); } foreach (var kv in this.PrimitiveMembers) { MemberInfo member = kv.Key; DbExpression exp = kv.Value; DbColumnAccessExpression cae = ObjectModelHelper.ParseColumnAccessExpression(sqlQuery, table, exp, member.Name); newModel.AddPrimitiveMember(member, cae); if (exp == this.PrimaryKey) { newModel.PrimaryKey = cae; if (this.NullChecking == this.PrimaryKey) { newModel.NullChecking = cae; } } } foreach (var kv in this.ComplexMembers) { MemberInfo member = kv.Key; IObjectModel val = kv.Value; ComplexObjectModel complexMemberModel = val.ToNewObjectModel(sqlQuery, table, dependentTable) as ComplexObjectModel; newModel.AddComplexMember(member, complexMemberModel); } if (newModel.NullChecking == null) { newModel.NullChecking = ObjectModelHelper.TryGetOrAddNullChecking(sqlQuery, table, this.NullChecking); } return(newModel); }
public void AddComplexMember(MemberInfo memberInfo, ComplexObjectModel model) { memberInfo = memberInfo.AsReflectedMemberOf(this.ObjectType); this.ComplexMembers.Add(memberInfo, model); }
public void AddConstructorParameter(ParameterInfo p, ComplexObjectModel complexModel) { this.ComplexConstructorParameters.Add(p, complexModel); }