コード例 #1
0
        /// <summary>
        /// 子类在查询接口方法中,调用此方法来向服务端执行指定的数据层查询方法,并返回满足条件的数据表格。
        /// </summary>
        /// <typeparam name="TRepository">子仓库的类型</typeparam>
        /// <param name="dataQueryExp">调用子仓库类中定义的数据查询方法的表达式。</param>
        /// <returns>返回满足条件的数据表格。</returns>
        protected LiteDataTable FetchTable <TRepository>(Expression <Func <TRepository, LiteDataTable> > dataQueryExp)
            where TRepository : EntityRepository
        {
            var ieqc = new IEQC();

            ParseExpToIEQC(dataQueryExp, ieqc);

            return(DataPortalFetchTable(ieqc));
        }
コード例 #2
0
        /// <summary>
        /// 子类在查询接口方法中,调用此方法来向服务端执行指定的数据层查询方法,并返回满足条件的实体列表。
        /// </summary>
        /// <typeparam name="TRepository">子仓库的类型</typeparam>
        /// <param name="dataQueryExp">调用子仓库类中定义的数据查询方法的表达式。</param>
        /// <returns>返回满足条件的实体列表。</returns>
        protected EntityList FetchList <TRepository>(Expression <Func <TRepository, EntityList> > dataQueryExp)
            where TRepository : EntityRepository
        {
            var ieqc = new IEQC();

            ParseExpToIEQC(dataQueryExp, ieqc);

            return(DataPortalFetchList(ieqc));
        }
コード例 #3
0
        private EntityList DataPortalFetchList(IEQC ieqc)
        {
            this.OnFetching(ieqc);

            var list = DataPortalApi.Fetch(this.GetType(), ieqc, this.DataPortalLocation) as EntityList;

            this.NotifyLoaded(list);

            return(list);
        }
コード例 #4
0
        /// <summary>
        /// 子类在查询接口方法中,调用此方法来导向服务端执行指定的数据层查询方法,并返回统计的行数。
        /// </summary>
        /// <typeparam name="TRepository">子仓库的类型</typeparam>
        /// <param name="dataQueryExp">调用子仓库类中定义的数据查询方法的表达式。</param>
        /// <returns>返回统计的行数。</returns>
        protected int FetchCount <TRepository>(Expression <Func <TRepository, EntityList> > dataQueryExp)
            where TRepository : EntityRepository
        {
            var ieqc = new IEQC {
                FetchType = FetchType.Count
            };

            ParseExpToIEQC(dataQueryExp, ieqc);

            return(DataPortalFetchList(ieqc).TotalCount);
        }
コード例 #5
0
        /// <summary>
        /// 子类在查询接口方法中,调用此方法来导向服务端执行指定的数据层查询方法,并返回第一个满足条件的实体。
        /// </summary>
        /// <typeparam name="TRepository">子仓库的类型</typeparam>
        /// <param name="dataQueryExp">调用子仓库类中定义的数据查询方法的表达式。</param>
        /// <returns>返回第一个满足条件的实体。</returns>
        protected Entity FetchFirst <TRepository>(Expression <Func <TRepository, EntityList> > dataQueryExp)
            where TRepository : EntityRepository
        {
            var ieqc = new IEQC {
                FetchType = FetchType.First
            };

            ParseExpToIEQC(dataQueryExp, ieqc);

            var list = DataPortalFetchList(ieqc);

            return(DisconnectFirst(list));
        }
コード例 #6
0
        /// <summary>
        /// 来自数据门户的数据查询
        /// </summary>
        /// <param name="criteria">The criteria.</param>
        /// <returns></returns>
        internal object PortalFetch(IEQC criteria)
        {
            //如果方法名为空,则使用约定的方法名。
            var methodName = criteria.MethodName ?? EntityConvention.GetByCriteriaMethod;
            var parameters = criteria.Parameters;

            object result = null;

            //先尝试在 DataProvider 中调用指定的方法,如果没有找到,才会调用 Repository 中的方法。
            if (!MethodCaller.CallMethodIfImplemented(
                    _dataProvider, methodName, parameters, out result
                    ))
            {
                result = MethodCaller.CallMethod(this, methodName, parameters);
            }

            return(result);
        }
コード例 #7
0
        /// <summary>
        /// 解析方法调用表达式,获取方法名及参数列表,存入到 IEQC 对象中。
        /// </summary>
        /// <param name="dataQueryExp"></param>
        /// <param name="ieqc"></param>
        private void ParseExpToIEQC(LambdaExpression dataQueryExp, IEQC ieqc)
        {
            dataQueryExp = Evaluator.PartialEval(dataQueryExp) as LambdaExpression;

            var methodCallExp = dataQueryExp.Body as MethodCallExpression;

            if (methodCallExp == null)
            {
                ExpressionNotSupported(dataQueryExp);
            }

            //repoExp 可以是仓库本身,也可以是 DataProvider,所以以下检测不再需要。
            //var repoExp = methodCallExp.Object as ParameterExpression;
            //if (repoExp == null || !repoExp.Type.IsInstanceOfType(this)) ExpressionNotSupported(dataQueryExp);

            //参数转换
            var arguments = methodCallExp.Arguments;

            ieqc.Parameters = new object[arguments.Count];
            for (int i = 0, c = arguments.Count; i < c; i++)
            {
                var argumentExp = arguments[i] as ConstantExpression;
                if (argumentExp == null)
                {
                    ExpressionNotSupported(dataQueryExp);
                }

                //把参数的值设置到数组中,如果值是 null,则需要使用参数的类型。
                ieqc.Parameters[i] = argumentExp.Value ??
                                     new MethodCaller.NullParameter {
                    ParameterType = argumentExp.Type
                };
            }

            //方法转换
            ieqc.MethodName = methodCallExp.Method.Name;
        }
コード例 #8
0
        public void Intercept(IInvocation invocation)
        {
            #region 预处理,根据返回值的类型来判断 FetchType。

            //if (Attribute.IsDefined(invocation.TargetType, typeof(IgnoreProxyAttribute))
            //    || Attribute.IsDefined(invocation.Method, typeof(IgnoreProxyAttribute)))
            //{
            //    invocation.Proceed();
            //    return;
            //}

            var fetchType  = RepositoryQueryType.List;
            var returnType = invocation.Method.ReturnType;
            if (returnType.IsClass)
            {
                if (typeof(EntityList).IsAssignableFrom(returnType))
                {
                    fetchType = RepositoryQueryType.List;
                }
                else if (typeof(Entity).IsAssignableFrom(returnType))
                {
                    fetchType = RepositoryQueryType.First;
                }
                else if (returnType == typeof(LiteDataTable))
                {
                    fetchType = RepositoryQueryType.Table;
                }
                else
                {
                    throw new NotSupportedException("仓库查询不支持返回 {0} 类型。".FormatArgs(returnType));
                }
            }
            else
            {
                fetchType = RepositoryQueryType.Count;
            }

            #endregion

            var ieqc = new IEQC
            {
                MethodName = invocation.Method.Name,
                Parameters = invocation.Arguments,
                QueryType  = fetchType
            };

            var repoExt = invocation.InvocationTarget as IRepositoryExt;
            var repo    = invocation.InvocationTarget as EntityRepository ?? repoExt.Repository as EntityRepository;

            //只是不要纯客户端,都直接使用本地访问
            if (repo.DataPortalLocation == DataPortalLocation.Local || RafyEnvironment.Location.ConnectDataDirectly)
            {
                using (FinalDataPortal.CurrentQueryCriteriaItem.UseScopeValue(ieqc))
                {
                    try
                    {
                        RafyEnvironment.ThreadPortalCount++;

                        if (repoExt != null)
                        {
                            //invoke repositoryExt
                            invocation.Proceed();
                        }
                        else
                        {
                            //先尝试在 DataProvider 中调用指定的方法,如果没有找到,才会调用 Repository 中的方法。
                            //这样可以使得 DataProvider 中定义同名方法即可直接重写仓库中的方法。
                            object result = null;
                            if (MethodCaller.CallMethodIfImplemented(
                                    repo.DataProvider, invocation.Method.Name, invocation.Arguments, out result
                                    ))
                            {
                                invocation.ReturnValue = result;
                            }
                            else
                            {
                                //invoke repository
                                invocation.Proceed();
                            }
                        }
                    }
                    finally
                    {
                        RafyEnvironment.ThreadPortalCount--;
                    }
                }
            }
            else
            {
                //调用数据门户,使得在服务端才执行真正的数据层方法。
                invocation.ReturnValue = DataPortalApi.Fetch(invocation.TargetType, ieqc, repo.DataPortalLocation);
            }

            #region Repository.NotifyLoaded

            switch (fetchType)
            {
            case RepositoryQueryType.List:
                var list = invocation.ReturnValue as EntityList;
                repo.NotifyLoaded(list);
                break;

            case RepositoryQueryType.First:
                var entity = invocation.ReturnValue as Entity;
                repo.NotifyLoaded(entity);
                break;

            case RepositoryQueryType.Count:
            case RepositoryQueryType.Table:
            default:
                break;
            }

            #endregion
        }