拼吾爱程序人生

首页 » .Net编程 » Linq » 扩展LINQ to SQL:使用Lambda Expression批量删除数据
cobra - 2008-3-5 22:57:00
文/赵劼  出处/博客园

  ORM框架在删除数据方面一直有个尴尬,那就是无法通过指定条件批量删除数据(当然这本不是ORM的问题,只是使用上感觉不方便)。于是对于一些删除操作,我们不得不写SQL语句或者执行存储过程,例如:

ItemDataContext db = new ItemDataContext();
db.ExecuteCommand(
    "DELETE FROM Item WHERE [CreateTime] < {0}",
    DateTime.UtcNow.AddMonths(-1));

  我始终认为,在程序里出现直接的SQL语句是一件很丑陋的事情。在我看来,数据库操作应该被封装起来,而对于应用层的开发人员来说,眼中应该只有对象——退一步的话也可向数据库发送指令(就是使用存储过程)。当然,这是理想状态,值得追求,但不可强求。幸运的是C# 3.0所拥有的强大特性足以让我们对LINQ to SQL的功能进行扩展。为了更好地进行项目开发,以及周五的一次技术交流,我为LINQ to SQL扩展了批量删除功能。当项目中引用了这个扩展之后,我们就可以使用如下的代码来实现上面的功能了:

ItemDataContext db = new ItemDataContext();
db.Items.Delete(item => item.CreateTime < DateTime.UtcNow.AddMonths(-1));

  当然,扩展还支持更复杂的删除条件,例如:

ItemDataContext db = new ItemDataContext();
db.Items.Delete(item =>
    item.CreateTime < DateTime.UtcNow.AddMonths(-1) ||
    item.ViewCount < item.CommentCount && item.UserName != "jeffz");

  之前我对于LINQ to SQL的扩展大都基于DataContext,不过很明显,这次的扩展是基于Table<T>的。总的来说,这个扩展比我想象中要简单不少。针对LINQ的扩展最麻烦的地方就在于解析表达式树(Expression Tree),而这个扩展关键的就是二元表达式(BinaryExpression),除了这点就没有太大问题了——当然,这也是因为我放弃了对于复杂表达式树的解析,例如现在就不支持“item.Introduction.Length < 10”这种条件,而对于更完整的解析方式来说,应该将其转化为T-SQL中的LEN函数。

  这个扩展的关键在于根据表达式树生成Where Condition,我使用三个步骤完成这个扩展,大家可以关注代码里的相关实现(如果需要的话我也可以在以后进行说明):

使用PartialEvaluator将表达式中的常量直接计算出来(例如“3 * 3”表达式将被替换为“9”),同时也会将一些存储在变量中的值使用常量进行替换。
使用ConditionBuilder将表达式中的常量收集起来,并生成带参数的Condition表达式(例如“[CreateTime] < {0} AND [UserName] <> {1}”)。
使用DataContext.ExecuteCommand方法执行完整的SQL语句。
  有了批量删除的功能,那么还缺点什么呢?那自然就是批量更新的功能了。批量更新的功能比删除略为复杂一些,我正在开发之中。在有了这个扩展之后,我们就可以使用如下的方法进行批量更新了:

ItemDataContext db = new ItemDataContext();
db.Items.Update(
    item => new Item
    {
        Introduction = item.Title + "Hello World",
        ViewCount = item.ViewCount + 1,
    }, // 更新方式
    item => item.CommentCount > 100 /* 更新条件 */);

  您可以
 附件: 您所在的用户组无法下载或查看附件我对批量删除的扩展。

 您可能对 [Linq] 的这些文章也感兴趣:

LINQ的演变及其对C# 设计的影响
使用LinqExtender轻松实现自定义LINQ提供器
Linq系列:基础与本质(Part I)
LINQ to XSD is Back
LINQ to SQL活学活用(3):嗅出“臭味”烟消云散
Linq to Sql--用存储过程更新数据库
PLINQ改名为Parallel Extensions发布
Presentation: Beth Massi on Conquering XML with LINQ in VB9
LINQ体验(8)——Union All/Intersect/Top/Bottom/Paging/SqlMethods
在LINQ to SQL中使用Translate方法以及修改查询用SQL
1
查看完整版本: 扩展LINQ to SQL:使用Lambda Expression批量删除数据
Modify by pin5i DZNT_ExpandPackage 2.1.3237 2007-2008 pin5i.com
  Total Unique Visitors: