今天在网上看到老赵前辈的扩展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
(this System.Data.Linq.Table source, Expression > 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