使用EF構建企業級應用(四)


本系列目錄:

使用EF構建企業級應用(一):主要講數據庫訪問基類IRepository及Repository 的實現

使用EF構建企業級應用(二):主要講動態排序擴展的實現

使用EF構建企業級應用(三):主要講靈活的構建查詢條件表達式Expression<Func<TEntity,bool>>.

使用EF構建企業級應用(四):主要講下在MVC環境中前端開發中如何使用,及一個實例源碼包

在前面三篇文章中,我們大致的描述了使用EF如何方便的實現數據持久化,我們簡要的回憶下都有那些關鍵的內容段

  • Repository基類的實現,
  • 查詢條件Expression<Func<T,bool>>的構建
  • 排序擴展

那么前端在使用MVC模式的時候,如何方便將我們前面所實現的銜接起來呢? 我們今天就來探討一下這個問題.

我們先來看看我們在實際項目中是如何使用的,如果你對這個寫法有興趣那再往下看(查詢界面我們采用JqGrid來展示數據)

 

         /// <summary>
        /// 查詢產品列表
        /// </summary>
        /// <returns></returns>
        public ActionResult GetProductList()
        {
            string json = string.Empty;
            if (WebRuntimes.LoginUser == null)
                return Content(GetAlertMessageJson("會話已過期,請重新登錄"));
            try
            {
                //構件查詢條件
                var queryParam = GetQueryParam<Product, PgQueryProductExp>();

                int total = 0;

                //查詢數據
                var lst = SysServices.GetProductList(queryParam, out total);
               
                //將lst轉化為jqgrid接受的json格式
                json = JsonForJqgrid(lst, total, queryParam.PageSize, queryParam.PageIndex);
            }
            catch (Exception ex)
            {
                Logger.Log(ELogType.Error, ex);
                json = GetAlertMessageJson("查詢失敗!");
            }

            return Content(json);
        }

也許你很快就發現了上述代碼中有兩個陌生的方法,構建查詢條件及從數據庫獲取數據,我們分別來看一下這兩個方法中都干了什么.

        • 首先我們來看看在控制器基類中的構建查詢條件的這個方法定義:
 
         /// <summary>
        /// 獲取頁面分頁查詢條件
        /// </summary>
        /// <typeparam name="TEntity">待查詢的實體</typeparam>
        /// <typeparam name="TPgQueryExp">頁面查詢轉化類型</typeparam>
        /// <returns></returns>
        protected EFQueryParam<TEntity> GetQueryParam<TEntity, TPgQueryExp>()
            where TEntity : class
            where TPgQueryExp : class, IEFQueryExpression<TEntity>, new()
        {
            string sidx = "Code";
            if (!string.IsNullOrEmpty(Request.QueryString["sidx"]))
            {
                sidx = Request.QueryString["sidx"].ToString();
            }
            bool isSordAsc = false;
            if (!string.IsNullOrEmpty(Request.QueryString["sord"]))
            {
                if (Request.QueryString["sord"].ToString() == "asc")
                {
                    isSordAsc = true;
                }
            }
            int pageSize = System.Convert.ToInt32(Request.QueryString["rows"]);
            int pageIndex = System.Convert.ToInt32(Request.QueryString["page"]) - 1;

            IEFQueryExpression<TEntity> exp = null;
            if (!string.IsNullOrEmpty(Request["d"]))
            {
                try
                {
                    exp = GetObjectOfJson<TPgQueryExp>(Microsoft.JScript.GlobalObject.unescape(Request["d"]));
                }
                catch
                { }
            }
            if (exp == null)
                exp = new TPgQueryExp();

            EFQueryParam<TEntity> ret = new EFQueryParam<TEntity>(exp, sidx, isSordAsc, pageIndex, pageSize);
            return ret;
        }
然后我們來看一下,代碼中有個陌生的對象PgQueryProductExp,那么他又做了什么呢?也許你已經猜到了,這個就是頁面查詢轉化條件的,來簡要的看一下是如何定義的
 

/// <summary>
    /// 頁面查詢產品條件
    /// </summary>
    public class PgQueryProductExp : IEFQueryExpression<Product>
    {
        public string Code { get; set; }
        public string Name { get; set; }
        public string Specification { get; set; }
        public Guid CategoryId { get; set; }
        public int EnableFlag { get; set; }

        public PgQueryProductExp()
        {
            EnableFlag = 1;
        }

        public Expression<Func<Product, bool>> GetExpression()
        {

            var exp = EFExpression<Product>.CreateSignleLogic(ELogicType.And)
                .Like(o => o.Code, Code)
                .Like(o => o.Name, Name)
                .Like(o => o.Specification, Specification);
            if (CategoryId != Guid.Empty)
                exp = exp.Equal(o => o.CategoryId, CategoryId);

            //條件中是否需要判斷是否有效?
            if (EnableFlag > -1)
            {
                exp = exp.Equal(o => o.IsEnabled, (EnableFlag == 1));
            }

            return exp.GetExpression();
        }

其次我們來看一下在SysService 這個服務層中,我們是如何實現查詢的
 

/// <summary>
       /// 查詢獲取產品數據
       /// </summary>
       /// <param name="queryParam">查詢參數</param>
       /// <param name="total">返回符合條件的記錄總數</param>
       /// <returns></returns>
       public IList<Product> GetProductList(EFQueryParam<Product> queryParam, out int total)
       {
           total = 0;
           IList<Product> lst = null;
           using (var repository = new Repository<Product>())
           {
               lst = repository.Include(o => o.ProductCategory).Get(queryParam, out total).ToList();
           }
           if (lst != null)
               lst = lst.Select(o => o.GetJsonEntity()).ToList();
           return lst;
       }

 

OK,這個就是一個完整的使用流程,貌似是很簡單的吧,不過細心的你也許已經發現了,我們在使用查詢的時候,貌似參查詢條件數並不是使用的在上一篇文章中的Expression<Func<T,bool>> 模式.而是使用這個EFQueryParam<T>類型.沒錯,我們在使用的時候,很多兄弟說,這個查詢方法的參數太多了,要求封裝一下,OK,那我們就來封裝一下吧

 

 

/// <summary>
    /// 封裝查詢參數
    /// </summary>
    /// <typeparam name="TExpression">參數類型</typeparam>
    public abstract class QueryParam<TExpression>
    {
        /// <summary>
        /// 查詢條件
        /// </summary>
        public TExpression Expression { get; set; }

        /// <summary>
        /// 排序字段
        /// </summary>
        public string OrderPropertyName { get; set; }

        /// <summary>
        /// 是否是升序排序,為false時則對OrderPropertyName采取降序排序
        /// </summary>
        public bool IsAscSort { get; set; }

        /// <summary>
        /// 分頁查詢,查詢第幾頁
        /// </summary>
        public int PageIndex { get; set; }

        /// <summary>
        /// 分頁查詢,每頁顯示記錄數
        /// </summary>
        public int PageSize { get; set; }

        /// <summary>
        /// 指示是否是分頁查詢
        /// </summary>
        public bool IsPagingQuery { get { return PageSize > 0; } }

    }
    /// <summary>
    /// EF 實現的 QueryParam
    /// </summary>
    /// <typeparam name="TEntity">條件關聯實體類型</typeparam>
    public class EFQueryParam<TEntity> : QueryParam<Expression<Func<TEntity, bool>>> where TEntity : class
    {
        /// <summary>
        /// 實例化新的 EFQueryParam 實例
        /// </summary>
        /// <param name="exp">查詢條件</param>
        /// <param name="orderPropertyName">排序屬性字段名</param>
        /// <param name="isAscSort">是否是升序排序,false為降序排序</param>
        /// <param name="pageIndex">分頁查詢,查詢第幾頁</param>
        /// <param name="pageSize">分頁查詢,每頁顯示記錄數</param>
        public EFQueryParam(Expression<Func<TEntity, bool>> exp, string orderPropertyName,
            bool isAscSort, int pageIndex, int pageSize)
        {
            this.Expression = exp;
            this.OrderPropertyName = orderPropertyName;
            this.IsAscSort = isAscSort;
            this.PageIndex = pageIndex;
            this.PageSize = pageSize;
        }

        /// <summary>
        /// 實例化新的 EFQueryParam 實例
        /// </summary>
        /// <param name="exp">查詢條件</param>
        /// <param name="orderPropertyName">排序屬性字段名</param>
        /// <param name="isAscSort">是否是升序排序,false為降序排序</param>
        /// <param name="pageIndex">分頁查詢,查詢第幾頁</param>
        /// <param name="pageSize">分頁查詢,每頁顯示記錄數</param>
        public EFQueryParam(IEFQueryExpression<TEntity> exp, string orderPropertyName,
            bool isAscSort, int pageIndex, int pageSize) :
            this(exp.GetExpression(), orderPropertyName, isAscSort, pageIndex, pageSize)
        {
        }

 

OK,大功告成.本系列也就寫完了, 你可以通過這里下載完整的源碼包去自己嘗試.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM