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> 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里的部分解析代码
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 > ? 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 - ));
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 = ; j < args.Count(); j++)
{
if (!(args[j].GetType() != "Type".GetType()))
{
args[j] = "'" + args[j] + "'";
}
}
if (args.Count() > )
{
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
EF批量添加,删除,修改的扩展的更多相关文章
- Entity Framework入门教程(12)--- EF进行批量添加/删除
EF6添加了批量添加/删除实体集合的方法,我们可以使用DbSet.AddRange()方法将实体集合添加到上下文,同时实体集合中的每一个实体的状态都标记为Added,在执行SaveChange()方法 ...
- MyBatis通过注解方式批量添加、修改、删除
唯能极于情,故能极于剑 注: 本文转载于:CodeCow · 程序牛 的个人博客:http://www.codecow.cn/ 一.数据库实体DO public class User implemen ...
- IIS环境下如何批量添加、修改、删除绑定的域名
IIS环境下如何批量添加和修改所绑定域名 1.关闭IISADMIN服务和W3SVC服务,可以从服务里面关闭,也可以直接执行命令:net stop iisadmin /y: 2.打开“C:\WINDOW ...
- EF批量添加数据性能慢的问题的解决方案
//EF批量添加数据性能慢的问题的解决方案 public ActionResult BatchAdd() { using (var db = new ToneRoad.CEA.DbContext.Db ...
- SQL语句添加删除修改字段及一些表与字段的基本操作
用SQL语句添加删除修改字段 1.增加字段 alter table docdsp add dspcode char(200)2.删除字段 ALTER TABLE table_NA ...
- Entity framework 绑定到Datagridview的添加删除修改
Entity framework 绑定到Datagridview的添加删除修改 using System; using System.Collections.Generic; using System ...
- JavaScript学习 - 基础(八) - DOM 节点 添加/删除/修改/属性值操作
html代码: <!--添加/删除/修改 --> <div id="a1"> <button id="a2" onclick=&q ...
- JTree 添加 , 删除, 修改
package com.swing.demo; import java.awt.BorderLayout; import java.awt.Container; import java.awt.eve ...
- 用SQL语句添加删除修改字段、一些表与字段的基本操作、数据库备份等
用SQL语句添加删除修改字段 1.增加字段 alter table docdsp add dspcode char(200) 2.删除字段 ALTER TABLE table_NAME DROP CO ...
- SQL语句添加删除修改字段[sql server 2000/2005]
用SQL语句添加删除修改字段1.增加字段 alter table docdsp add dspcodechar(200)2.删除字段 ALTER TABLE table_NAME ...
随机推荐
- RTC终于tm的通了
ITDS(1316336566) 2014-1-16 10:34:36我们板子上用的是pcf8563默认没使用这个,用图形界面选择下这个完以后,在配置下就这两步骤ITDS(1316336566) 2 ...
- Unity3d之Perfab
对于重复使用的游戏体可以将其制作成Perfab.首先在Project窗口中选择[Create]-[Prefab]创建一个空的Perfab.然后将该重复使用的游戏体拖到这个空的Perfab上就OK了. ...
- php一些常规动态设置与获取
error_reporting(E_ALL); ini_set('display_errors', TRUE); ini_set('display_startup_errors', TRUE);ini ...
- zookper3.4.6集群配置
参考链接: http://blog.csdn.net/shirdrn/article/details/7183503 个人感觉zookeeper 安装在单机上无操作意义,所以直接记录集群配置过程. 连 ...
- 【转】如何读懂Oracle文档中的语法图
转自:http://blog.itpub.net/22990797/viewspace-750157/ Oracle文档中用到了两种表达语法的方法,语法图和BNF. BNF, Backus-Naur ...
- 插入数据insert语句中出错:没有与这些操作数匹配的“+”运算符,操作数类型为:const char[ ]+CString
UpdateData(); CString n; n.Format(L"%d", m_n); _bstr_t strCmd_n = "insert into n(材料,折 ...
- 定义的函数在main中调用时提示找不到标识符
要把定义的函数放在main函数前,如果放在main函数后了,要在main前做声明.声明就是把函数定义的首部一行加一个分号放在main之前. 在c语言中自定义了一个函数,在main中调用时提示找不到标识 ...
- 笔记:php有那几种错误提示和查错方法
php有哪几种错误提示 1.notice : 注意 2.waring : 警告 3.error : 错误 PHP中都有哪几种查错方法? 1.语法检查--php配置文件里,把错误显示选项都打开或者代码开 ...
- HTML&CSS精选笔记_列表与超链接
列表与超链接 列表标记 无序列表ul 无序列表的各个列表项之间没有顺序级别之分,是并列的 <ul> <li>列表项1</li> <li>列表项2< ...
- swift -- 如何在swift下,使用类似oc的pch文件功能
以前在做oc下的项目的时候,pch文件是必创建的,因为实在是太方便了,只要在build setting里面把pch的路径换成绝对路径,那么剩下的,想干什么就在里面干什么,但是swift下,可以实现这种 ...