1.1、
Code1: |
using (PubsDataContext pubsContent = new PubsDataContext()) |
{ |
pubsContent.Log = Console.Out; |
Author author = pubsContent.Authors.Single(a => a.au_id == "111-11-1111"); |
pubsContent.Authors.DeleteOnSubmit(author); |
pubsContent.SubmitChanges(); |
} |
可是,马上我的程序支持到这里就跑不动了,第二行有异常。
为什么呢?
看一下MSDN关于Signle方法的说明:
哦,问题出在这里,Single要求符合条件的记录有且只有一行,否则就会发飙。
从以前的学习中我知道,调用Single方法时DataContent即刻从数据库中获取数据库,而这个时间如果获取不到auid="111-11-1111"的记录,返回的记录集是空的,就引发了上面的异常。
1.2、
我想找一个方法,让Linq不执行Select而直接Delete,搜完了MSDN,翻完了《LINQ in Action》,没有。
后来我想,既然Linq to sql有“延迟加载”功能,那么删除时能不能也“延迟”呢,我尝试这样:
Code 2: |
using (PubsDataContext pubsContent = new PubsDataContext()) |
{ |
var q = from a in pubsContent.Authors |
where a.au_id == "111-11-1111" |
select a; |
pubsContent.Log = Console.Out; |
pubsContent.Authors.DeleteAllOnSubmit(q); |
pubsContent.SubmitChanges(); |
} |
我的程序被驯服了,不在这里发飙了。
难道Linq to sql真如我所想的直接执行delete from Authors where au_id='111-11-1111'这样的语句了吗?
2.1
带着上面的疑问,一步一步跟踪查看DataContent的Log。我发现,在用Single()方法来删除的时候,如果不出现异常,提交的SQL语句是这样的。
这里可以很清楚看出,Linq先从数据库中取出记录,然后再Delete。我们知道主键就可以确定表中唯一的记录了,可是为什么删除条件要把所有的列都加进去呢?老赵在这个post(在Linq to Sql中管理并发更新时的冲突[1],[2],[3] )里很详细的说明了这个问题。
我的目的只是要删除一行记录,可是这样使用Linq to sql却先从数据库里取出来再删除,实在是多此一举。那Code 2中的方法又是如何运行的呢?我们再来跟踪它。
2.2
为了更好的说明问题,我把Code 1中的代码改一下,另外还在数据库中预先添加二行记录,au_id分别为111-11-1111、111-11-1112
Code 3: |
using (PubsDataContext pubsContent = new PubsDataContext()) |
{ |
pubsContent.Log = Console.Out; |
var q = from a in pubsContent.Authors |
where a.au_id.StartsWith("111-11-111") |
select a; |
pubsContent.Authors.DeleteAllOnSubmit(q); |
pubsContent.SubmitChanges(); |
} |
把==条件换成了StartsWith(生成SQL语句时,StartWith会生成Like '111-11-111%'匹配)。
现在再下这段代码执行的Log:
SELECT [t0].[au_id], [t0].[au_lname], [t0].[au_fname], [t0].[phone], [t0].[address], [t0].[city], [t0].[state], [t0].[zip], [t0].[contract] |
FROM [dbo].[authors] AS [t0] |
您可能想查找下面的文章:文章分类 |