Linq To Sql 简单的单表批量删除

简介:

      今天在网上看到老赵前辈的扩展LINQ to SQL:使用Lambda Expression批量删除数据,我看完了文章,还没有看源代码,我一般都习惯于在看别人的代码前,思考一下如果我来实现我会如何实现。我想了许久操作表达式树操作二元表达式(BinaryExpression)我是肯定困难的,对于表达式类库的了解不多,用了Reflector反射,结果什么都看不见,也许我的Reflector版本低了,没有更新。我就放弃了这种实现方式,我想有没有其他的方式呢?最终我觉得可以操作生成sql执行同样可以达到目的,也许更简单化。

      如何获取sql呢,Linq中有db.GetCommand(IQueryable )方法,DBCommand的CommandText就是sql了,那我们如何获取IQueryable 呢,我的第一感觉就是where方法。所以就有下面的语句了,IQueryable q = source.Where(query).AsQueryable();     DbCommand cmd = db.GetCommand(q);

     现在我们等到了查询sql,如何转化为Delete呢,我用了正则表达式匹配。就得到了下面完全代码:

复制代码
public   static   class  TableExtension
    {
        
///  
        
///  单表操作批量删除
        
///  
        
///  
        
///  
        
///  
        
///  
         public   static   int  Delete < T > ( this  System.Data.Linq.Table < T >  source, Expression < Func < T,  bool >>  query)
            
where  T :  class
        {
            
if  (source  ==   null )
                
throw   new  ArgumentException( " source " );
            
if  (query  ==   null )
                
throw   new  ArgumentException( " query " );
            
// query = t => true;
            
// 为空DELETE  FROM [dbo].[test] 全删除;个人觉得为空全删除,很不人道,所以还是抛异常
            System.Data.Linq.DataContext db  =  source.Context;
            IQueryable q 
=  source.Where(query).AsQueryable();
            DbCommand cmd 
=  db.GetCommand(q);
            
string  sql  =  cmd.CommandText;
            
string  regex  =
        
@" from\s*\[\s*dbo\s*\]\s*\.\s*\[\s*\w+\s*\]\s*(?(as\s*(?(\[\s*\w+\s*\]))))(\.|(\r)|(\n))* " ;
            MatchCollection matches 
=  Regex.Matches(sql, regex, RegexOptions.Multiline  |  RegexOptions.IgnoreCase);
            Debug.Assert(matches 
!=   null " regex match :null " );
            Debug.Assert(matches.Count 
==   1 " regex match length : "   +  matches.Count);
            
if  (matches  !=   null   &&  matches.Count  >   0 )
            {
                Match match 
=  matches[ 0 ];
                sql 
=  ( " DELETE   "   +  match.Value.Replace(match.Groups[ " tableparam " ].Value,  "" +
                    sql.Substring(match.Index 
+  match.Length)).Replace(match.Groups[ " tablepname " ].Value  +   " . " "   " );
                List
< object >  dbparams  =   new  List < object > ();
                
foreach  (SqlParameter item  in  cmd.Parameters)
                {
                    SqlParameter p 
=   new  SqlParameter(item.ParameterName, item.SqlDbType, item.Size);
                    p.Value 
=  item.Value;
                    dbparams.Add(item.Value);
                }
                q 
=   null ;
                cmd 
=   null ;
                matches 
=   null ;
                Debug.WriteLine(
" delete sql : "   +  sql);
                
return  db.ExecuteCommand(sql, dbparams.ToArray());


            }
            
return   0 ;
        }
复制代码

 现在我们可以进行批量删除了,如:

DataContext.test.Delete(t  =>  t.id  >   0   &&  t.name.Contains( " test " ||   new   string [] {  " 12 " " 34 " " 45 "  }.Contains(t.name) 

&&   t.name.Length  > 1 );

是不是很简单:看看Debug输出的sql:

image

在看一个:

  
DataContext.Orders.Delete(t  =>   ! t.EmployeeID1.HasValue);
image

这个扩展中的缺点:

1:只针对对单表操作,不支持linq的连接,如:DataContext.test.Delete(t => t.Orders.OrderID > 0);我这个我认为这个可以通过一个更复杂正则表达式完成。还有一种思路更简洁,就是通过sql server支持的表变量或者是临时表先查询出结果,在根据主键实现删除。也许你会说可以写成存储过程,我个人不喜欢它,我一般尽量在程序中TSQL,移植性好,除非性能考虑采用存储过程。

2:事务处理:在这里只是一个先前的测试Demo,所以么有考虑。我觉得我们可以建立一个类来管理sql语句或者查询条件表达式在调用save方法时候进行内部事务操作(我一般不喜欢将事务显示在外部,因为我觉得事务很费资源,等待时间过长数据库容易崩溃,或者对表的锁定等,不知道这个想法对不对,请大家给个建议)。现在可以在外部事务操作就是有点像ADO.NET了,呵呵麻烦。

优点:

1:可以支持复杂的表达式,想老赵提到的“item.Introduction.Length < 10“,以及后面评论中提到的in、like等。

2:实现简单,操作简单,这是最重要的,代码很容易理解。

3:执行不需要从数据库里取出实体在执行,这是Linq的做法。更符合我们的习惯。我看见在老赵博客最后一个评论说它用EF也实现了批量删除,它的那种方式是取出实体在delete,其实并不是EF特有的,Linq也完全可以实现,就几行代码而已。

   

    还想多写一些优点,暂时就想到这些,有什么Bug或者建议请大家一定要指出。还有就是不知道这样对内存有么有影响,还没有来得及测试。

     我个人觉得其实计算机的东西都是我们生活中简单的问题运用,就在个人的思维了,就和前面讲的老外Linq组合查询的PredicateExtensions类一样。

 

    恩现在赶紧去看看老赵前辈的实现方式了,还没来得及看过一行代码呢,不知对事务、多表的支持如何。


作者:破  狼 
出处:http://www.cnblogs.com/whitewolf/ 
本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-个人独立博客博客园--破狼51CTO--破狼。https://yq.aliyun.com/articles/new?spm=5176.100239.yqblognav1.2.soBjhr


相关文章
|
人工智能 文字识别 监控
将人工智能融入多媒体 助力视频产业加速——阿里云视频AI全能力解读
结合人工智能视频理解流程和用户的需求场景,我们将视频AI的功能分成四个大部分,视频智能审核、视频内容理解、视频智能编辑、视频版权保护。其中视频审核功能包括视频鉴黄、暴恐涉政识别、广告二维码识别、无意义直播识别等,利用识别能力将网络上没营养和不健康的视频内容进行排查和处理;视频理解功能包括视频分类、标签,人物识别、语音识别,同时也包括对视频中的文字进行识别(OCR);视频编辑层面可以实现视频首图、视频摘要、视频highlight的生成,同时支持新闻拆条;关于视频版权,支持视频相似性、同源视频检索和音视频指纹等功能。
17650 0
将人工智能融入多媒体 助力视频产业加速——阿里云视频AI全能力解读
|
SQL 存储 BI
如何在 SQL Server 中使用 `CONCAT`
【8月更文挑战第10天】
1001 3
如何在 SQL Server 中使用 `CONCAT`
|
消息中间件 存储 分布式计算
Hadoop学习笔记(HDP)-Part.19 安装Kafka
01 关于HDP 02 核心组件原理 03 资源规划 04 基础环境配置 05 Yum源配置 06 安装OracleJDK 07 安装MySQL 08 部署Ambari集群 09 安装OpenLDAP 10 创建集群 11 安装Kerberos 12 安装HDFS 13 安装Ranger 14 安装YARN+MR 15 安装HIVE 16 安装HBase 17 安装Spark2 18 安装Flink 19 安装Kafka 20 安装Flume
349 0
Hadoop学习笔记(HDP)-Part.19 安装Kafka
|
9月前
|
前端开发 JavaScript C++
Marp 教程:实现幻灯片动画效果
Marp 是一个基于 Markdown 的幻灯片制作工具,结合 VSCode 的强大编辑功能,可以让你的 PPT 制作更加高效和专业。本教程详细介绍了如何在 Marp 中使用 CSS 和 JavaScript 实现幻灯片的动画效果,包括淡入、滑动、旋转等基本动画,以及交互式动画和图表动画等高级效果。通过这些技巧,你可以制作出更加生动、吸引眼球的演示文稿。
287 0
|
JavaScript 前端开发 C++
如何理解 QML_ELEMENT QML_SINGLETON staic Foo *create(QQmlEngine *, QJSEngine *){return s instance; }
如何理解 QML_ELEMENT QML_SINGLETON staic Foo *create(QQmlEngine *, QJSEngine *){return s instance; }
178 2
|
SpringCloudAlibaba 双11 Sentinel
七.SpringCloudAlibaba极简入门-Sentinel熔断
在上一章节我们探讨了Sentinel的流控(限流)功能,Sentinel除了流控还提供了服务熔断和降级机制,服务之间的调用关系错综复杂,微服务的调用链上的某些服务资源不稳定(宕机,异常,超时)可能会导致可能请求的失败和请求的堆积,调用链产生连锁反应可能会导致整个微服务架构瘫痪。服务熔断降级机制是保障高可用的重要措施之一。
2023阿里云com域名续费优惠口令来了
2023阿里云com域名续费又涨价了,com域名续费价格79元一年,使用优惠口令“商标优选即买即用”后优惠价为72元一年。
3362 0
2023阿里云com域名续费优惠口令来了
|
Windows
撤销与取消撤销快捷键
通常有时候需要撤销操作,或者撤销点快了要取消撤销。 记录下如何操作。
1515 0
|
人工智能 移动开发 自然语言处理
天猫精灵AliGenie-技能开发体验
以往,对于天猫精灵的理解,更多的是居于方糖音响产品。然而,它的语音交互功能才是王炸,尤其是在可以自定义交互语言的情况下!以下便是基于开发者平台展示的简单操作,此次展示的是作为个人使用,因此完全可以零基础操作。
1484 0
天猫精灵AliGenie-技能开发体验
|
Ubuntu Shell Linux
ImageMagick 命令行下图像处理的利器
ImageMagick是一系列的用于修改、加工图像的命令行工具。ImageMagick能够快速地使用命令行对图片进行操作,对大量的图片进行批处理,或者是集成到bash脚本里去。
655 0
ImageMagick 命令行下图像处理的利器