EntityFramework動態多條件查詢與Lambda表達式樹 +分頁查詢

初次使用linq to sql 對於查詢語句還不熟悉,特此記錄下

查詢分頁方法(轉)

    /// <summary>
        /// 分頁查詢 + 條件查詢 + 排序
        /// </summary>
        /// <typeparam name="Tkey">泛型</typeparam>
        /// <param name="pageSize">每頁大小</param>
        /// <param name="pageIndex">當前頁碼</param>
        /// <param name="total">總數量</param>
        /// <param name="whereLambda">查詢條件</param>
        /// <param name="orderbyLambda">排序條件</param>
        /// <param name="isAsc">是否升序</param>
        /// <returns>IQueryable 泛型集合</returns>
        public IQueryable<_dpsui_logs> LoadPage_log<Tkey>(int pageSize, int pageIndex, out int total, Expression<Func<_dpsui_logs, bool>> whereLambda, Func<_dpsui_logs, Tkey> orderbyLambda, bool isAsc)
        {
            total = MyBaseDbContext.Set<keyou_dpsui_logs>().Where(whereLambda.Compile()).Count();
            if (isAsc)
            {
                var temp = MyBaseDbContext.Set<_dpsui_logs>().Where(whereLambda.Compile())
                             .OrderBy<_dpsui_logs, Tkey>(orderbyLambda)
                             .Skip(pageSize * (pageIndex - 1))
                             .Take(pageSize);
                return temp.AsQueryable();
            }
            else
            {
                var temp = MyBaseDbContext.Set<keyou_dpsui_logs>().Where(whereLambda.Compile())
                           .OrderByDescending<_dpsui_logs, Tkey>(orderbyLambda)
                           .Skip(pageSize * (pageIndex - 1))
                           .Take(pageSize);
                return temp.AsQueryable();
            }
        }
使用多條件查詢幫助類需要修改的地方
MyBaseDbContext.Set<keyou_dpsui_logs>().Where(whereLambda)
修改爲:
MyBaseDbContext.Set<keyou_dpsui_logs>().Where(whereLambda.Compile())

多條件查詢幫助類

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace DPS
{
   public static class DynamicLinqExpressions
    {
        //多條件查詢幫助類
        public static Expression<Func<T, bool>> True<T>() { return f => true; }
        public static Expression<Func<T, bool>> False<T>() { return f => false; }

        //注意this
        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
                                                            Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>
                  (Expression.Or(expr1.Body, invokedExpr), expr1.Parameters);
        }

        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
                                                             Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>
                  (Expression.And(expr1.Body, invokedExpr), expr1.Parameters);
        }
    }
}

對於上面的修改做了下修改,由於多條件查詢用到了上面的連接的方法。在執行時報錯了,於是在網上再到了如下解決辦法
來源:https://www.cnblogs.com/fengri/p/3376431.html
在這裏插入圖片描述

修改後運行正常

正常調用

  var eps = DynamicLinqExpressions.True<_dpsui_logs>();// 多條件查詢集合
            DateTime date =DateTime.Parse( dateTimeInput1.Value.ToString("yyyy-MM-dd "));
            if (date.ToString().Split('/')[0] != "0001")
            {
                //關於時間 由於需求是查詢特定某一天的數據。數據庫中 時間字段包含 00:00:00
                //於是轉換了下
                eps=eps.And(u =>u.time.Value.ToString("yyyy-MM-dd ") == date.ToString("yyyy-MM-dd "));
            }
            string username = txtuserName.Text;
            if (username != "")
            {
                eps = eps.And(u => u.username == username);
            }
            string opt = comboBox1.SelectedItem.ToString();
            if (opt != "請選擇")
            {
                eps = eps.And(u => u.opt == opt);
            }
            int pagesize = int.Parse(cmd_pagecount.SelectedItem.ToString());//每頁顯示多少條數據
            int count = 0;//返回的頁數
            //調用分頁
            var log = dPShelper.LoadPage_log(pagesize, CurrentPage, out count, eps, u => u.id, true);
            txtpage.Text = count.ToString();//有多少條數據
            txtpagesizeCount.Text = string.Format("{0}", (count + 1) / pagesize + 1); ;//得到總頁數
            txtpagesize.MaxValue = int.Parse(txtpagesizeCount.Text);

            DGV1.AutoGenerateColumns = false;
            DGV1.DataSource = log.ToList();//綁定數據的時候要 toLisst() 不然會報異常

更新2018-10-09

由於要查詢兩張表A和B,
要根據A中的ID查詢B表中相應的數量
所以更新了下分頁

/// <summary>
        /// card_A 是自己定義的實體類
        /// </summary>
        /// <returns></returns>
        //已髮卡查詢
        public IQueryable<Log.card_A> LoadPage_dpcinfo<Tkey>(int pageSize, int pageIndex, out int total, Expression<Func<dpcinfo, bool>> whereLambda, Func<dpcinfo, Tkey> orderbyLambda, bool isAsc)
        {
            total = MyBaseDbContext.Set<dpcinfo>().Where(whereLambda).Count();
            if (isAsc)
            {
                var temp = MyBaseDbContext.Set<dpcinfo>()
                                .Where(whereLambda)
                                .OrderBy<dpcinfo, Tkey>(orderbyLambda)
                                .Skip(pageSize * (pageIndex - 1))
                                .Take(pageSize)
                                .GroupJoin(MyBaseDbContext.cardda_mxz, d => d.dpcid, c => c.dpcid, (d, c) => new Log.card_A { dpcid = d.dpcid, addr = d.addr, count_add = c.Count() }) ;
                return temp.AsQueryable();
            }
            else
            {
                var temp = MyBaseDbContext.Set<dpcinfo>()
                               .OrderByDescending<dpcinfo, Tkey>(orderbyLambda)
                               .Skip(pageSize * (pageIndex - 1))
                               .Take(pageSize)
                                .GroupJoin(MyBaseDbContext.cardda_mxz, d => d.dpcid, c => c.dpcid, (d, c) => new Log.card_A { dpcid = d.dpcid, addr = d.addr, count_add = c.Count() });
                return temp.AsQueryable();
            }

        }

注意:Log.card_A是自己定義的實體類。根據界面上需要顯示的數據源定義的一個實體類
在這裏插入圖片描述
綁定數據
在這裏插入圖片描述

做了個查詢優化
1、當用戶查詢 刷新時,從當前頁開始刷新,不會跳轉到第一頁
2、當顯示行數增加,觸發查詢時,如當前頁*顯示頁數超過數據總量時,自動顯示最後一頁
反之正常顯示當前頁數

 public void GOselect_card()
        {
            int pagesize = int.Parse(txtpageNow_card.Text);//當前頁數
            int pagesizeCount = int.Parse(txtpagesizeCount_card.Text);//總頁數
            int pagecount = int.Parse(cmd_pagecount_card.SelectedItem.ToString());//顯示多少條
            int count_user = int.Parse(txtpage_card.Text);//總條數
            if (pagesize > 0 || pagesize <= pagesizeCount)
            {
                if ((pagesize * pagecount) > count_user && count_user != 0)
                {
                    txtpageNow_card.Value = int.Parse(txtpagesizeCount_card.Text);//最大頁數
                    pagesizeCount = (count_user - 1) / pagecount + 1;//得到總頁數
                    selectcard(pagesizeCount);
                }
                else
                {
                    selectcard(pagesize);
                }
            }
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章