Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        //暂时去除
        ///// <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);
        }