EF批量添加,刪除,修改的擴展


在EF各版本中,沒有相應批量的添加,刪除,修改,在用ORM 處理數據時直有個尷尬。在網上,也接到了很多網友的詢問這方面的情況,特此今天把這方面的相關擴展分享一下,(這里只做批量刪除的例子,添加和修改的思路雷同)

一、原由

     在先前的SQL操作中,我們要

update table set  cl=1 where  id>5 and id<100

delete from table where  id>5 and id<100

但是在EF中沒有提供相應的接口,我們只能這樣

 

//批量刪除
foreach(var user in context.table.Where(u => u.id>5 and id<100).ToList()) { context.Remove(user); }
 
        

 

本來一句sql可以解決的問題,現在變得復雜了。

二,擴展思路

     雖然EF沒有提供的接口中,不過我們可以進行一個擴展(EF里面是指定自己SQL語句 context.Database.ExecuteSqlCommand(sql,args)),思路是這樣的

    通過EF擴展 生成 SQL語句 讓EF來執行SQL

三,具體實現代碼(自己擴展的實現,具體看源碼)

  1.應用代碼

 

     DB<MdStudent> db = new DB<MdStudent>();
                     db.Remove(u => u.id>5 and id<100);

 

2.代碼分析
     DB<MdStudent> db = new DB<MdStudent>();//這實例化一個context類,這類里封裝了EF方法及擴展

        db.Remove(u => u.id>5 and id<100);//這里主要執行了三個操作,1.確認是哪個表,2,Lambda生成SQL,這里用到了ConditionBuilder類,PartialEvaluator類來解析成SQL

     以上是PartialEvaluator里的部分解析代碼

   

        public void Build(Expression expression)
        {
            PartialEvaluator evaluator = new PartialEvaluator();
            Expression evaluatedExpression = evaluator.Eval(expression);

            this.m_arguments = new List<object>();
            this.m_conditionParts = new Stack<string>();

            this.Visit(evaluatedExpression);

            this.Arguments = this.m_arguments.ToArray();
            this.Condition = this.m_conditionParts.Count > 0 ? this.m_conditionParts.Pop() : null;
        }

        protected override Expression VisitBinary(BinaryExpression b)
        {
            if (b == null) return b;

            string opr;
            switch (b.NodeType)
            {
                case ExpressionType.Equal:
                    opr = "=";
                    break;
                case ExpressionType.NotEqual:
                    opr = "<>";
                    break;
                case ExpressionType.GreaterThan:
                    opr = ">";
                    break;
                case ExpressionType.GreaterThanOrEqual:
                    opr = ">=";
                    break;
                case ExpressionType.LessThan:
                    opr = "<";
                    break;
                case ExpressionType.LessThanOrEqual:
                    opr = "<=";
                    break;
                case ExpressionType.AndAlso:
                    opr = "AND";
                    break;
                case ExpressionType.OrElse:
                    opr = "OR";
                    break;
                case ExpressionType.Add:
                    opr = "+";
                    break;
                case ExpressionType.Subtract:
                    opr = "-";
                    break;
                case ExpressionType.Multiply:
                    opr = "*";
                    break;
                case ExpressionType.Divide:
                    opr = "/";
                    break;
                default:
                    throw new NotSupportedException(b.NodeType + "is not supported.");
            }
            this.Visit(b.Left);
            this.Visit(b.Right);
            string right = this.m_conditionParts.Pop();
            string left = this.m_conditionParts.Pop();
            string condition = String.Format("({0} {1} {2})", left, opr, right);
            this.m_conditionParts.Push(condition);
            return b;
        }

        protected override Expression VisitConstant(ConstantExpression c)
        {
            if (c == null) return c;
            this.m_arguments.Add(c.Value);
            this.m_conditionParts.Push(String.Format("{{{0}}}", this.m_arguments.Count - 1));
            return c;
        }
        protected override Expression VisitMemberAccess(MemberExpression m)
        {
            if (m == null) return m;
            PropertyInfo propertyInfo = m.Member as PropertyInfo;
            if (propertyInfo == null) return m;
            this.m_conditionParts.Push(String.Format("[{0}]", propertyInfo.Name));
            return m;
        }

 

3.組裝SQL

 

 /// <summary>
        /// 刪除擴展[優化刪除]
        /// </summary>
        public static int DeleteEntity<Entity>(this EFDbContext<Entity> Context, Expression<Func<Entity, bool>> Predicate) where Entity : class,IEntity
        {
            Command cmd = GetCommands<Entity>(Predicate);
            int Result = Context.Database.ExecuteSqlCommand(cmd.Text, cmd.args);
            return Result;
        }
        public static CommSql GetDeleteSql<Entity>(this EFDbContext<Entity> Context, Expression<Func<Entity, bool>> Predicate, bool IsFag) where Entity : class,IEntity
        {
            Command com = GetCommands<Entity>(Predicate);
            string CommText = com.Text;
            object[] args = com.args;
            for (int j = 0; j < args.Count(); j++)
            {
                if (!(args[j].GetType() != "Type".GetType()))
                {
                    args[j] = "'" + args[j] + "'";
                }
            }
            if (args.Count() > 0)
            {
                CommText = string.Format(CommText, args);
            }
            CommSql cmd = new CommSql();
            cmd.Text = CommText;
            if (IsFag)
                cmd.ComNum = Context.Database.ExecuteSqlCommand(com.Text, com.args);
            return cmd;
        }
        private static Command GetCommands<Entity>(Expression<Func<Entity, bool>> Predicate) where Entity : class,IEntity
        {
            //根據條件表達式轉換成SQL的條件語句
            ConditionBuilder Builder = new ConditionBuilder();
            Builder.Build(Predicate.Body);
            string sqlCondition = Builder.Condition;
            //獲取SQL參數數組 
            string Table = Operate.getTableName<Entity>();
            string CommText = "Delete  From  [" + Table + "] Where " + sqlCondition;
            var args = Builder.Arguments;
            return new Command() { Text = CommText, args = args };
        }

 

以上只是部分代碼,詳細看擴展代碼及實現例子 http://files.cnblogs.com/gzalrj/EF5.rar

   


    

   

 

     

 

 

 


免責聲明!

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



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