예제 #1
0
        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);
        }