internal IQuery BuildQuery(Expression exp) { var mainTable = f.Table(_repo); _query = f.Query(mainTable); mainTable.Alias = QueryGenerationContext.Get(_query).NextTableAlias(); this.Visit(exp); return(_query); }
protected override Expression VisitMethodCall(MethodCallExpression exp) { var method = exp.Method; _isAny = method.Name == LinqConsts.EnumerableMethod_Any; //先访问表达式 book.ChapterList.Cast<Chapter>(),获取列表属性。 var invoker = exp.Arguments[0]; _parentPropertyFinder.Find(invoker); var listPropertyTable = _parentPropertyFinder.PropertyOwnerTable; var listProperty = _parentPropertyFinder.Property as IListProperty; if (listProperty == null) { throw EntityQueryBuilder.OperationNotSupported(invoker); } //为该列表对应的实体创建表对象、查询对象。 var childRepo = RepositoryFactoryHost.Factory.FindByEntity(listProperty.ListEntityType); var childTable = f.Table(childRepo); _query = f.Query( from: childTable, selection: f.Literal("1") ); var qgc = QueryGenerationContext.Get(_parentQuery); qgc.Bind(_query); childTable.Alias = qgc.NextTableAlias(); //Any、All 方法如果有第二个参数,那么第二个参数就是条件表达式。如:c => c.Name == chapterName if (exp.Arguments.Count == 2) { var reverseWhere = !_isAny;//如果是 All,则需要反转里面的所有操作符。 var queryBuilder = new EntityQueryBuilder(childRepo, reverseWhere); queryBuilder.BuildQuery(exp.Arguments[1], _query); } //添加子表查询与父实体的关系条件:WHERE c.BookId = b.Id var parentProperty = childRepo.FindParentPropertyInfo(true); var parentRefIdProperty = (parentProperty.ManagedProperty as IRefProperty).RefIdProperty; var toParentConstraint = f.Constraint(childTable.Column(parentRefIdProperty), listPropertyTable.IdColumn); _query.Where = f.And(toParentConstraint, _query.Where); return(exp); }
//暂时去除 ///// <summary> ///// 在查询对象中查找或者创建指定引用属性对应的连接表对象。 ///// </summary> ///// <param name="propertyOwner">聚合子属性所在的实体对应的表。也是外键关系中主键表所在的表。</param> ///// <param name="childrenProperty">指定的聚合子属性。</param> ///// <returns></returns> //internal ITableSource FindOrCreateJoinTable(ITableSource propertyOwner, IListProperty childrenProperty) //{ // if (childrenProperty.HasManyType != HasManyType.Composition) throw new InvalidProgramException("只能对聚合子属性使用此方法。"); // //先找到这个关系对应的引用属性。 // var refEntityType = childrenProperty.ListEntityType; // var refRepo = RepositoryFactoryHost.Factory.FindByEntity(refEntityType); // var parentProperty = refRepo.FindParentPropertyInfo(true); // var parentRef = (parentProperty.ManagedProperty as IRefProperty).RefIdProperty; // var refTableSource = _allJoinTables.FirstOrDefault( // ts => ts.RefProperty == parentRef && ts.PrimaryKeyTable == propertyOwner // ); // if (refTableSource == null) // { // var f = QueryFactory.Instance; // var fkTable = f.Table(refRepo, QueryGenerationContext.Get(this).NextTableAlias()); // refTableSource = AddJoinTable(fkTable, parentRef, propertyOwner, fkTable); // } // return refTableSource.ForeignKeyTable; //} /// <summary> /// 在查询对象中查找或者创建指定引用属性对应的连接表对象。 /// </summary> /// <param name="propertyOwner">引用属性所在的实体对应的表。也是外键关系中外键列所在的表。</param> /// <param name="refProperty">指定的引用属性。</param> /// <returns></returns> internal ITableSource FindOrCreateJoinTable(ITableSource propertyOwner, IRefEntityProperty refProperty) { var refTableSource = _allJoinTables.FirstOrDefault( ts => ts.ForeignKeyTable == propertyOwner && ts.RefProperty == refProperty ); if (refTableSource == null) { var f = QueryFactory.Instance; var refEntityType = refProperty.RefEntityType; var refRepo = RepositoryFactoryHost.Factory.FindByEntity(refEntityType); var pkTable = f.Table(refRepo, QueryGenerationContext.Get(this).NextTableAlias()); refTableSource = AddJoinTable(propertyOwner, refProperty, pkTable, pkTable); } return(refTableSource.PrimaryKeyTable); }