entity framework 批量更新,批量刪除,分頁 的擴展函數


   在前面的博客就分別提到了要實現批量更新和刪除的函數,今天我也終於實現了.現在拿出來跟大家分享一下吧.

  我們先來說批量刪除吧.請看代碼

 

        public static int Delete<T>(this ObjectSet<T> ent, Expression<Func<T, bool>> where) where T : class
        {
            var query = ent.Where(where);
            ObjectQuery objQuery = query as ObjectQuery;
           string sql=objQuery.ToTraceString();
           sql = "delete " + sql.Substring(sql.IndexOf("from", StringComparison.OrdinalIgnoreCase));
           sql = sql.Replace("[Extent1].", "").Replace("AS [Extent1]", "").Replace("__linq__", "");
           List<object> objs = new List<object>();
           foreach (var para in objQuery.Parameters)
           {
               objs.Add(para.Value);
           }
          int index= ent.Context.ExecuteStoreCommand(sql, objs.ToArray());
          return index;

        }

刪除其實也並不難,主要是通過查詢語句,作相應的修改就行了.

我們再看,修改語句.

 

 public static int Update<T>(this ObjectSet<T> ent, Expression<Func<T, bool>> where, Expression<Func<T>> updater) where T : class
        {
            //where 語句
            var query = ent.Where(where);
            ObjectQuery objQuery = query as ObjectQuery;
            List<object> objParams = new List<object>();            
            string sql = objQuery.ToTraceString();
            sql = sql.Substring(sql.IndexOf("from", StringComparison.OrdinalIgnoreCase)).Replace("__linq__", "");
            int paramindex = objQuery.Parameters.Count;
            foreach (var para in objQuery.Parameters)
            {
                objParams.Add(para.Value);
            }
            //獲取Update的賦值語句
            var valueObj = updater.Compile().Invoke();
            MemberInitExpression updateMemberExpr = (MemberInitExpression)updater.Body;
            StringBuilder updateBuilder = new StringBuilder();          
            Type valueType = typeof(T);
            foreach (var bind in updateMemberExpr.Bindings.Cast<MemberAssignment>())
            {
                string name = bind.Member.Name;
                updateBuilder.AppendFormat("{0}=@p{1},", name, paramindex++);                
                var value = valueType.GetProperty(name).GetValue(valueObj);           
                objParams.Add(value);
            }
            if (updateBuilder.Length == 0)
            {
                throw new Exception("請填寫要更新的值");
            }
            else
            {
                sql = " update [Extent1] set " + updateBuilder.Remove(updateBuilder.Length - 1, 1).ToString() + " " + sql;
            }
            int index = ent.Context.ExecuteStoreCommand(sql, objParams.ToArray());
            return index;

        }

  修改,折騰了我不少時間,關鍵就是那個賦值語句,折騰了不少時間,一開始都把時間花費在表達樹上,這也是網上找到的.但看網上的那個修改語句,都是有問題,主要是在修改時,對於參數化的賦值,做不了.只能修改 常量的值,這對我們的使用是有非常大的限制.

  后來,突發靈感.想到了,先用表達樹,計算出Expression<Func<T>> updater的值,然后再把那得出來的值,弄成參數,傳進去.就這樣,解決了參數化傳值的問題.

  關於這方法,曾經有網友反對過.說直接用sql,就行了.比較簡單. 在這里,我想解釋一下,我堅持要寫,處於2個方面考慮. 一是,方便開發人員開發.因為這個的寫法就是典型的lingq寫法. 二是,我覺的,作為一個框架, 我們要把能統一的東西,統一起來,這樣以后有什么變動,維護起來也比較方便.如果我們直接用sql語句,就會比較亂,不便於后期的維護.

   下面我們就看看批量刪除和修改,調用的方便性吧.

        ec.testEnt.Update(ent =>ent.MonthlyDataID==new Guid("95134D1D-2647-4F84-B82A-DB84B0BC382E") ,
                      ()=> new BMW_MonthlyDataDetail2() { CreationUser = "2012-12-1",CreationDate=DateTime.Parse("2012-10-2"),ModificaitonUser=value });



        ec.testEnt.Delete(ent => ent.MonthlyDataID == new Guid("95134D1D-2647-4F84-B82A-DB84B0BC382E"));

看我們刪除和修改是否都很方便啊.?

  當然,我這個批量刪除和修改是不支持多表的.因為那個批量刪除和修改多表,用的地方不多,而且實現起來很麻煩.所以就沒有去實現了.

下面我們再看分頁的函數吧.

        //分頁
        public static IQueryable<T> Page<T, TResult>(this IQueryable<T> query, int pageIndex, int pageSize, Expression<Func<T, TResult>> orderByProperty, bool isAscendingOrder, out int rowsCount)
        {
            if (pageSize <= 0) pageSize = 20;

            rowsCount = query.Count();

            if (rowsCount <= pageSize || pageIndex <= 0) pageIndex = 1;

            int excludedRows = (pageIndex - 1) * pageSize;

            if (orderByProperty != null)
            {
                if (isAscendingOrder)
                    query = query.OrderBy(orderByProperty);
                else
                    query = query.OrderByDescending(orderByProperty);
            }         
            if (pageIndex == 1)
                return query.Take(pageSize);
            else
                return query.Skip(excludedRows).Take(pageSize);
        }

我們把分頁,也用一個函數統一起來,這樣開發人員分頁的時候,就不會每個人都有自己的一套了.

下面我再把這個類的整體代碼弄出來吧.

 

View Code
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Data.Objects;
  4 using System.Linq;
  5 using System.Linq.Expressions;
  6 using System.Text;
  7 using System.Threading.Tasks;
  8 
  9 namespace System.Linq
 10 {
 11     public static class LinqExt
 12     {
 13         //分頁
 14         public static IQueryable<T> Page<T>(this IQueryable<T> query, int pageIndex, int pageSize)
 15         {
 16             int total;
 17            return  Page<T>(query, pageIndex, pageSize);
 18         }
 19 
 20         //分頁
 21         public static IQueryable<T> Page<T>(this IQueryable<T> query, int pageIndex, int pageSize, out int total)
 22         {
 23             Expression<Func<T, string>> order = null;
 24             return Page(query, pageIndex, pageSize, order, false, out total);
 25         }
 26 
 27         //分頁
 28         public static IQueryable<T> Page<T, TResult>(this IQueryable<T> query, int pageIndex, int pageSize, Expression<Func<T, TResult>> orderByProperty, bool isAscendingOrder, out int rowsCount)
 29         {
 30             if (pageSize <= 0) pageSize = 20;
 31 
 32             rowsCount = query.Count();
 33 
 34             if (rowsCount <= pageSize || pageIndex <= 0) pageIndex = 1;
 35 
 36             int excludedRows = (pageIndex - 1) * pageSize;
 37 
 38             if (orderByProperty != null)
 39             {
 40                 if (isAscendingOrder)
 41                     query = query.OrderBy(orderByProperty);
 42                 else
 43                     query = query.OrderByDescending(orderByProperty);
 44             }         
 45             if (pageIndex == 1)
 46                 return query.Take(pageSize);
 47             else
 48                 return query.Skip(excludedRows).Take(pageSize);
 49         }
 50 
 51       
 52 
 53         public static int Delete<T>(this ObjectSet<T> ent, Expression<Func<T, bool>> where) where T : class
 54         {
 55             var query = ent.Where(where);
 56             ObjectQuery objQuery = query as ObjectQuery;
 57            string sql=objQuery.ToTraceString();
 58            sql = "delete " + sql.Substring(sql.IndexOf("from", StringComparison.OrdinalIgnoreCase));
 59            sql = sql.Replace("[Extent1].", "").Replace("AS [Extent1]", "").Replace("__linq__", "");
 60            List<object> objs = new List<object>();
 61            foreach (var para in objQuery.Parameters)
 62            {
 63                objs.Add(para.Value);
 64            }
 65           int index= ent.Context.ExecuteStoreCommand(sql, objs.ToArray());
 66           return index;
 67 
 68         }
 69 
 70         public static int Update<T>(this ObjectSet<T> ent, Expression<Func<T, bool>> where, Expression<Func<T>> updater) where T : class
 71         {
 72             //where 語句
 73             var query = ent.Where(where);
 74             ObjectQuery objQuery = query as ObjectQuery;
 75             List<object> objParams = new List<object>();            
 76             string sql = objQuery.ToTraceString();
 77             sql = sql.Substring(sql.IndexOf("from", StringComparison.OrdinalIgnoreCase)).Replace("__linq__", "");
 78             int paramindex = objQuery.Parameters.Count;
 79             foreach (var para in objQuery.Parameters)
 80             {
 81                 objParams.Add(para.Value);
 82             }
 83             //獲取Update的賦值語句
 84             var valueObj = updater.Compile().Invoke();
 85             MemberInitExpression updateMemberExpr = (MemberInitExpression)updater.Body;
 86             StringBuilder updateBuilder = new StringBuilder();          
 87             Type valueType = typeof(T);
 88             foreach (var bind in updateMemberExpr.Bindings.Cast<MemberAssignment>())
 89             {
 90                 string name = bind.Member.Name;
 91                 updateBuilder.AppendFormat("{0}=@p{1},", name, paramindex++);                
 92                 var value = valueType.GetProperty(name).GetValue(valueObj);           
 93                 objParams.Add(value);
 94             }
 95             if (updateBuilder.Length == 0)
 96             {
 97                 throw new Exception("請填寫要更新的值");
 98             }
 99             else
100             {
101                 sql = " update [Extent1] set " + updateBuilder.Remove(updateBuilder.Length - 1, 1).ToString() + " " + sql;
102             }
103             int index = ent.Context.ExecuteStoreCommand(sql, objParams.ToArray());
104             return index;
105 
106         }
107 
108     }
109 }

 

希望我這個類,對大家有幫助,同時也希望各位網友,提出你們寶貴的意見,讓我們共同進步吧.

 

 

 

 

 

 

 

 

 

 


免責聲明!

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



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