扩展LINQ to SQL

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/*更新条件*/);

您可以下载我对批量删除的扩展。

本文配套源码

时间: 2024-09-12 11:17:42

扩展LINQ to SQL的相关文章

Linq To SQL 批量更新方法汇总

方法一.官方例子 地球人都知道的,也是不少 Linq To SQL 反对者认为效率低下的一种方法. NorthwindDataContext db = new NorthwindDataContext();var customers = db.Customers.Where(c => c.CustomerID.StartsWith("BL"));foreach (var customer in customers){ customer.Address = "Guangz

LINQ To SQL在N层应用程序中的CUD操作、批量删除、批量更新

原文:LINQ To SQL在N层应用程序中的CUD操作.批量删除.批量更新 0. 说明     Linq to Sql,以下简称L2S.    以下文中所指的两层和三层结构,分别如下图所示:       准确的说,这里的分层并不是特别明确:(1) 生成的DataContext(Linq t0 SQL Runtime)和Entity是放在一个文件中的,物理上不能切割开来:上图只是展示逻辑上的结构.(2) 拿上图右边的三层结构来说,鉴于第(1)点,UI层就可以跨越BusinessLogic层,直接

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

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

一起谈.NET技术,Linq To SQL 批量更新方法汇总

方法一.官方例子 地球人都知道的,也是不少 Linq To SQL 反对者认为效率低下的一种方法. NorthwindDataContext db = new NorthwindDataContext(); var customers = db.Customers.Where(c => c.CustomerID.StartsWith("BL")); foreach (var customer in customers) { customer.Address = "Gua

Linq to SQL对象的增删改

你的程序里,是否到处充斥着这种代码: db.Customers.InsertOnSubmit(customer); db.SubmitChange(); 如果某一天,因为 Customers 表的数据库巨增,需要把它拆成两个表,你是否会胆寒???当然,对于查询,我们可以通过视图来解决.对于插入,或者更新呢?据说,现在的数据库在某些情况下,可以对视图进行数据的更新.插入.但是我们要考虑的是不可以的情况.是不是得每个地方都改呀?对于一个大型的项目,这种改动是很可怕的,某个地方少改了,就糟糕了.不过,

测试运行: 使用LINQ测试SQL存储过程

对访问和操作后端 SQL Server 数据库的程序进行测试十分常见.在此类情况中,应用程序基本都是通过使用 SQL 存储过程来与后端数据进行交互的.此时,可将存储过程看作待测试系统的辅助方法:因此也必须像系统中的任何其他模块一样测试它们. 尽管在测试 SQL 存储过程时可使用的方法有很多,但我发现使用 LINQ 可极大地简化测试自动化.在本月的专栏中,我将向您展示如何使用 LINQ(尤其是使用 LINQ to SQL 提供程序)来测试 SQL 存储过程.我将假定您的 C# 和 SQL 技能属于

学Linq to sql(一):预备知识

什么是Linq to sql Linq to sql(或者叫DLINQ)是LINQ(.NET语言集成查询)的一部分,全称基于关系数据的 .NET 语言集成查询,用于以对象形式管理关系数据,并提供了丰富的查询功能,它和Linq to xml .Linq to objects.Linq to dataset.Linq to entities等组成了强大的LINQ. 要学好LINQ查询语法,就不得不先理解C# 3.0的一些新特性,下面一一简单介绍. 隐含类型局部变量 var age = 26; var

LINQ to SQL异步查询

异步操作是提高Web应用程序吞吐量的重要手段,关于这方面的话题已经在前 文<正确使用异步操作>中解释过了.对于大多数互联网应用来说,性能瓶颈数 据库访问.换句话说,一个请求在数据库操作上所花的时间往往是最多的 --并且占总时间的90%以上.因此,当Web应用程序的吞吐量因为数 据库操作的阻塞而受到影响的话,我们可是尝试使用异步数据库操作来进行优化 . 如果我们使用LINQ to SQL,在默认情况下是无法实现异步查询的,所 有的操作都非常自然--异步是不自然的,因为它把连续的操作拆成 了两段.

ADO.NET与ORM的比较(3) Linq to SQL实现CRUD

说明:个人感觉在Java领域大型开发都离不了ORM的身影,所谓的SSH就是 Spring+Struts+Hibernate,除了在学习基础知识的时候被告知可以使用JDBC操 作数据库之外,大量的书籍中都是讲述使用Hibernate这个ORM工具来操作数据. 在.NET中操作数据库的方式有多种,除了最直接的方式就是使用ADO.NET之外, 还可以使用NHibernate这个Hibernate在.NET中的实现ORM,如果你对第三方的 ORM 持怀疑态度,你还可以使用来自微软的实现.根正苗红的Lin