mvc entity framework 多條件 查詢

 

mvc entity framework 多條件 查詢

分類: mvc 170人閱讀 評論(0) 收藏 舉報

mvc 多條件查詢時,不想用拼接的方式,搜索了一圈,記錄一下過程,最初採用 如下代碼

[csharp] view plaincopy
  1.     public static class PredicateExtensions  
  2.        {  
  3.   
  4.            public static Expression<Func<T, bool>> True<T>() { return f => true; }  
  5.            public static Expression<Func<T, bool>> False<T>() { return f => false; }  
  6.   
  7.            public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expression1, Expression<Func<T, bool>> expression2)  
  8.            {  
  9.                var invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());  
  10.                return Expression.Lambda<Func<T, bool>>(Expression.Or(expression1.Body, invokedExpression), expression1.Parameters);  
  11.            }  
  12.            public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1, Expression<Func<T, bool>> expression2)  
  13.            {  
  14.                var invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());  
  15.                return Expression.Lambda<Func<T, bool>>(Expression.And(expression1.Body, invokedExpression), expression1.Parameters);  
  16.            }  
  17.    }  
  18.   
  19. 用如下:  
  20.   
  21. /// <summary>  
  22.        /// 獲取用戶列表 分頁  
  23.        /// </summary>  
  24.        /// <param name="pageIndex">頁碼</param>  
  25.        /// <param name="pageSize">每頁記錄數</param>  
  26.        /// <param name="paras">查詢參數</param>  
  27.        /// <returns></returns>  
  28.        public List<NewUser> GetUserList(int pageIndex, int pageSize, Dictionary<string,string> paras, out int totalcount)  
  29.        {  
  30.            totalcount=db.LsNewUsers.Count();  
  31.            int startRow=(pageIndex-1)*pageSize;  
  32.            return db.LsNewUsers.AsNoTracking().Where(<span style="color:#ff0000;">GetExpression(paras).Compile</span>()).OrderBy(u => u.UserId).Skip(startRow).Take(pageSize).ToList();  
  33.        }  
  34.   
  35.        /// <summary>  
  36.        /// 獲取查詢條件 表達式樹  
  37.        /// </summary>  
  38.        /// <param name="dicParam">參數列表</param>  
  39.        /// <returns></returns>  
  40.        public Expression<Func<NewUser, bool>> GetExpression(Dictionary<string,string> dicParam)  
  41.        {  
  42.            //個人理解,類似 賦給一個初始 條件 1=1 和 and方法一起用; 如果是false方法,類似賦給一個初始條件1!=1,和or方法一起用.  
  43.            Expression<Func<NewUser, bool>> searchPredicate = PredicateExtensions.True<NewUser>();  
  44.            foreach (string key in dicParam.Keys)  
  45.            {  
  46.                string condition = string.Empty;  
  47.                switch (key.ToLower())  
  48.                {  
  49.                    case "username"//case自己擴展  
  50.                        condition = dicParam[key];  
  51.                        searchPredicate = searchPredicate.And(c => c.UserName.IndexOf(condition)>-1);  
  52.                        break;  
  53.                  case "sex":  
  54.                        condition = dicParam[key];  
  55.                        bool blsex=true;  
  56.                        bool.TryParse(condition,out blsex);  
  57.                        searchPredicate = searchPredicate.And(c => c.Sex==blsex);  
  58.                        break;  
  59.                    default:  
  60.                        break;  
  61.                }  
  62.            }  
  63.            return searchPredicate;  
  64.        }  


重點是這一句:

db.LsNewUsersWhere( condition.Compile()).OrderBy(u => u.UserId).Skip(startRow).Take(pageSize).ToList();

可以通過,但是 會出現 http://bbs.csdn.net/topics/390254489 中出現的問題,查詢時,sql profiler 監視發現是查詢全部表。

於是我去掉 complie方法,發現會出現 The LINQ expression node type 'Invoke' is not supported in LINQ to Entities 的錯誤


網上找了一圈。發現可以使LinqKit.dll 來解決這個entity framework中的這個問題

參考文章:http://www.albahari.com/nutshell/predicatebuilder.aspx

剛開始 百度搜了一個linqkit.dll,雖然方法有,但是錯誤依舊。。抱着試一試的態度,找到了上面文章中的linqkit的地址。下載下來,錯誤消失。

dll 下載地址:http://www.albahari.com/nutshell/LinqKit.zip

相關文章:http://www.albahari.com/nutshell/linqkit.aspx

怕國外的網站不行,自己也上傳了一份,地址:http://download.csdn.net/detail/laokaizzz/7167477


因爲我用的是 ef,所以得使用dll,又因爲是。net 4.0 不是 4.5,不能直接從nuget裏安裝,所以直接引用的dll.


最終代碼

使用如下:

   /// <summary>
        /// 獲取用戶列表 分頁
        /// </summary>
        /// <param name="pageIndex">頁碼</param>
        /// <param name="pageSize">每頁記錄數</param>
        /// <param name="paras">查詢參數</param>
        /// <returns></returns>
        public List<NewUser> GetUserList(int pageIndex, int pageSize, Dictionary<string,string> paras, out int totalcount)
        {
            int startRow=(pageIndex-1)*pageSize;
             Expression<Func<NewUser, bool>> condition=GetExpression(paras);

             totalcount = db.LsNewUsers.AsExpandable().Where(condition).Count();//獲取總數 AsExpandable是linqkit.dll中的方法
             return db.LsNewUsers.AsExpandable().Where(condition).OrderBy(u => u.UserId).Skip(startRow).Take(pageSize).ToList();
        }

        /// <summary>
        /// 獲取查詢條件 表達式樹
        /// </summary>
        /// <param name="dicParam">參數列表</param>
        /// <returns></returns>
        public Expression<Func<NewUser, bool>> GetExpression(Dictionary<string,string> dicParam)
        {
            //個人理解,類似 賦給一個初始 條件 1=1 和 and方法一起用; 如果是false方法,類似賦給一個初始條件1!=1,和or方法一起用.
            Expression<Func<NewUser, bool>> searchPredicate = PredicateBuilder.True<NewUser>();
            foreach (string key in dicParam.Keys)
            {
                string condition = string.Empty;
                switch (key.ToLower())
                {
                    case "username": //case自己擴展
                        condition = dicParam[key];
                        searchPredicate = searchPredicate.And(c => c.UserName.IndexOf(condition)>-1);
                        break;
                  case "sex":
                        condition = dicParam[key];
                        bool blsex=true;
                        bool.TryParse(condition,out blsex);
                        searchPredicate = searchPredicate.And(c => c.Sex==blsex);
                        break;
                    default:
                        break;
                }
            }
            return searchPredicate;
        }

轉載來自於:http://blog.csdn.net/laokaizzz/article/details/23255367
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章