在EF各版本中,没有相应批量的添加,删除,修改,在用ORM 处理数据时直有个尴尬。在网上,也接到了很多网友的询问这方面的情况,特此今天把这方面的相关扩展分享一下,(这里只做批量删除的例子,添加和修改的思路雷同)

一、原由

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

  1. update table set cl=1 where id>5 and id<100
  2.  
  3. delete from table where id>5 and id<100

但是在EF中没有提供相应的接口,我们只能这样

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

本来一句sql可以解决的问题,现在变得复杂了。

二,扩展思路

虽然EF没有提供的接口中,不过我们可以进行一个扩展(EF里面是指定自己SQL语句 context.Database.ExecuteSqlCommand(sql,args)),思路是这样的

通过EF扩展 生成 SQL语句 让EF来执行SQL

三,具体实现代码(自己扩展的实现,具体看源码)

1.应用代码

  1. DB<MdStudent> db = new DB<MdStudent>();
  2. db.Remove(u => u.id> and id<);

2.代码分析
     DB<MdStudent> db = new DB<MdStudent>();//这实例化一个context类,这类里封装了EF方法及扩展

db.Remove(u => u.id> and id<);//这里主要执行了三个操作,1.确认是哪个表,2,Lambda生成SQL,这里用到了ConditionBuilder类,PartialEvaluator类来解析成SQL

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

  1. public void Build(Expression expression)
  2. {
  3. PartialEvaluator evaluator = new PartialEvaluator();
  4. Expression evaluatedExpression = evaluator.Eval(expression);
  5.  
  6. this.m_arguments = new List<object>();
  7. this.m_conditionParts = new Stack<string>();
  8.  
  9. this.Visit(evaluatedExpression);
  10.  
  11. this.Arguments = this.m_arguments.ToArray();
  12. this.Condition = this.m_conditionParts.Count > ? this.m_conditionParts.Pop() : null;
  13. }
  14.  
  15. protected override Expression VisitBinary(BinaryExpression b)
  16. {
  17. if (b == null) return b;
  18.  
  19. string opr;
  20. switch (b.NodeType)
  21. {
  22. case ExpressionType.Equal:
  23. opr = "=";
  24. break;
  25. case ExpressionType.NotEqual:
  26. opr = "<>";
  27. break;
  28. case ExpressionType.GreaterThan:
  29. opr = ">";
  30. break;
  31. case ExpressionType.GreaterThanOrEqual:
  32. opr = ">=";
  33. break;
  34. case ExpressionType.LessThan:
  35. opr = "<";
  36. break;
  37. case ExpressionType.LessThanOrEqual:
  38. opr = "<=";
  39. break;
  40. case ExpressionType.AndAlso:
  41. opr = "AND";
  42. break;
  43. case ExpressionType.OrElse:
  44. opr = "OR";
  45. break;
  46. case ExpressionType.Add:
  47. opr = "+";
  48. break;
  49. case ExpressionType.Subtract:
  50. opr = "-";
  51. break;
  52. case ExpressionType.Multiply:
  53. opr = "*";
  54. break;
  55. case ExpressionType.Divide:
  56. opr = "/";
  57. break;
  58. default:
  59. throw new NotSupportedException(b.NodeType + "is not supported.");
  60. }
  61. this.Visit(b.Left);
  62. this.Visit(b.Right);
  63. string right = this.m_conditionParts.Pop();
  64. string left = this.m_conditionParts.Pop();
  65. string condition = String.Format("({0} {1} {2})", left, opr, right);
  66. this.m_conditionParts.Push(condition);
  67. return b;
  68. }
  69.  
  70. protected override Expression VisitConstant(ConstantExpression c)
  71. {
  72. if (c == null) return c;
  73. this.m_arguments.Add(c.Value);
  74. this.m_conditionParts.Push(String.Format("{{{0}}}", this.m_arguments.Count - ));
  75. return c;
  76. }
  77. protected override Expression VisitMemberAccess(MemberExpression m)
  78. {
  79. if (m == null) return m;
  80. PropertyInfo propertyInfo = m.Member as PropertyInfo;
  81. if (propertyInfo == null) return m;
  82. this.m_conditionParts.Push(String.Format("[{0}]", propertyInfo.Name));
  83. return m;
  84. }

3.组装SQL

  1. /// <summary>
  2. /// 删除扩展[优化删除]
  3. /// </summary>
  4. public static int DeleteEntity<Entity>(this EFDbContext<Entity> Context, Expression<Func<Entity, bool>> Predicate) where Entity : class,IEntity
  5. {
  6. Command cmd = GetCommands<Entity>(Predicate);
  7. int Result = Context.Database.ExecuteSqlCommand(cmd.Text, cmd.args);
  8. return Result;
  9. }
  10. public static CommSql GetDeleteSql<Entity>(this EFDbContext<Entity> Context, Expression<Func<Entity, bool>> Predicate, bool IsFag) where Entity : class,IEntity
  11. {
  12. Command com = GetCommands<Entity>(Predicate);
  13. string CommText = com.Text;
  14. object[] args = com.args;
  15. for (int j = ; j < args.Count(); j++)
  16. {
  17. if (!(args[j].GetType() != "Type".GetType()))
  18. {
  19. args[j] = "'" + args[j] + "'";
  20. }
  21. }
  22. if (args.Count() > )
  23. {
  24. CommText = string.Format(CommText, args);
  25. }
  26. CommSql cmd = new CommSql();
  27. cmd.Text = CommText;
  28. if (IsFag)
  29. cmd.ComNum = Context.Database.ExecuteSqlCommand(com.Text, com.args);
  30. return cmd;
  31. }
  32. private static Command GetCommands<Entity>(Expression<Func<Entity, bool>> Predicate) where Entity : class,IEntity
  33. {
  34. //根据条件表达式转换成SQL的条件语句
  35. ConditionBuilder Builder = new ConditionBuilder();
  36. Builder.Build(Predicate.Body);
  37. string sqlCondition = Builder.Condition;
  38. //获取SQL参数数组
  39. string Table = Operate.getTableName<Entity>();
  40. string CommText = "Delete From [" + Table + "] Where " + sqlCondition;
  41. var args = Builder.Arguments;
  42. return new Command() { Text = CommText, args = args };
  43. }

以上只是部分代码,详细看扩展代码及实现例子 http://files.cnblogs.com/gzalrj/EF5.rar

EF批量添加,删除,修改的扩展的更多相关文章

  1. Entity Framework入门教程(12)--- EF进行批量添加/删除

    EF6添加了批量添加/删除实体集合的方法,我们可以使用DbSet.AddRange()方法将实体集合添加到上下文,同时实体集合中的每一个实体的状态都标记为Added,在执行SaveChange()方法 ...

  2. MyBatis通过注解方式批量添加、修改、删除

    唯能极于情,故能极于剑 注: 本文转载于:CodeCow · 程序牛 的个人博客:http://www.codecow.cn/ 一.数据库实体DO public class User implemen ...

  3. IIS环境下如何批量添加、修改、删除绑定的域名

    IIS环境下如何批量添加和修改所绑定域名 1.关闭IISADMIN服务和W3SVC服务,可以从服务里面关闭,也可以直接执行命令:net stop iisadmin /y: 2.打开“C:\WINDOW ...

  4. EF批量添加数据性能慢的问题的解决方案

    //EF批量添加数据性能慢的问题的解决方案 public ActionResult BatchAdd() { using (var db = new ToneRoad.CEA.DbContext.Db ...

  5. SQL语句添加删除修改字段及一些表与字段的基本操作

    用SQL语句添加删除修改字段 1.增加字段     alter table docdsp    add dspcode char(200)2.删除字段     ALTER TABLE table_NA ...

  6. Entity framework 绑定到Datagridview的添加删除修改

    Entity framework 绑定到Datagridview的添加删除修改 using System; using System.Collections.Generic; using System ...

  7. JavaScript学习 - 基础(八) - DOM 节点 添加/删除/修改/属性值操作

    html代码: <!--添加/删除/修改 --> <div id="a1"> <button id="a2" onclick=&q ...

  8. JTree 添加 , 删除, 修改

    package com.swing.demo; import java.awt.BorderLayout; import java.awt.Container; import java.awt.eve ...

  9. 用SQL语句添加删除修改字段、一些表与字段的基本操作、数据库备份等

    用SQL语句添加删除修改字段 1.增加字段 alter table docdsp add dspcode char(200) 2.删除字段 ALTER TABLE table_NAME DROP CO ...

  10. SQL语句添加删除修改字段[sql server 2000/2005]

    用SQL语句添加删除修改字段1.增加字段     alter table docdsp    add dspcodechar(200)2.删除字段     ALTER TABLE table_NAME ...

随机推荐

  1. 矩阵的特征值和特征向量的雅克比算法C/C++实现

    矩阵的特征值和特征向量是线性代数以及矩阵论中很重要的一个概念.在遥感领域也是经经常使用到.比方多光谱以及高光谱图像的主成分分析要求解波段间协方差矩阵或者相关系数矩阵的特征值和特征向量. 依据普通线性代 ...

  2. 转载:mysql如果数据不存在,则插入新数据,否则更新的实现方法

    转自:http://www.jb51.net/article/28885.htm //如果不存在,则插入新数据 $sql = "INSERT INTO {$ecs->table(‘ca ...

  3. HTML input只能输入数字

    onkeyup="this.value=this.value.replace(/[^0-9]/g,'')" onafterpaste="this.value=this.v ...

  4. Struts2 ajax json使用介绍

    一.jar包首先引入Struts和json所需的jar包. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXRteWhvbWUxOTkw/font/5a6 ...

  5. 阿里云ACE下的PHP开发环境搭建

    阿里云ACE下的PHP开发环境搭建 本系列文章由ex_net(张建波)编写.转载请注明出处. http://blog.csdn.net/ex_net/article/details/23999053 ...

  6. c++ 参赛设置

    void report(LogWriter& lw); 代表引用原对象 void report(LogWriter lw); 代表重新拷贝构造一个对象

  7. ubuntu设置中文拼音输入法

    转载  http://www.cnblogs.com/zhj5chengfeng/archive/2013/06/23/3150620.html

  8. Windows路径操作API函数学习

    前言 在VC++开发过程中,经常需要用到一些路径操作,比如拼需要的文件路径,搜索路径中的内容等等.Windows提供了一套关于路径操作的API帮助我们更好的执行这些操作. 路径截断与合并API Pat ...

  9. SVN入门 TortoiseSVN 检出

    1. SVN检出(SVN Checkout) 检出项目文件. 新建或者进入目录下(比如qianduan1),右键 --> Svn 检出-->其中版本库URL我可以在SVN服务器获取到,将复 ...

  10. mongodb 安装(windows mongodb 安装)

    MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的.他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型.M ...