源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

Linq to SQL Delete时遇到问题的解决方法

  • 时间:2020-04-30 18:06 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:Linq to SQL Delete时遇到问题的解决方法
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();
}
可是,马上我的程序支持到这里就跑不动了,第二行有异常。 [url=http://www.1sucai.cn/upload/20080314191821197.png][img]http://files.jb51.net/upload/20080314191822101.png[/img] [/url] 为什么呢? 看一下MSDN关于Signle方法的说明: [url=http://www.1sucai.cn/upload/20080314191822774.png][img]http://files.jb51.net/upload/20080314191822454.png[/img] [/url] 哦,问题出在这里,Single要求符合条件的记录[b]有且只有一行[/b],否则就会发飙。 从以前的学习中我知道,调用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语句是这样的。 [img]http://files.jb51.net/upload/20080314191822933.png[/img] 这里可以很清楚看出,Linq先从数据库中取出记录,然后再Delete。我们知道主键就可以确定表中唯一的记录了,可是为什么删除条件要把所有的列都加进去呢?[url=http://www.cnblogs.com/JeffreyZhao/]老赵[/url]在这个post([url=http://www.cnblogs.com/JeffreyZhao/archive/2007/10/30/Solving-Concurrent-Conflict-Problem-in-Linq-to-Sql.html]在Linq to Sql中管理并发更新时的冲突[1][/url],[url=http://www.cnblogs.com/JeffreyZhao/archive/2007/11/20/solving-concurrent-conflict-problem-in-linq-to-sql-2.html][2][/url],[url=http://www.cnblogs.com/JeffreyZhao/archive/2007/11/23/Solving-Concurrent-Conflict-Problem-in-Linq-to-Sql-3-using-timestamp.html][3][/url] )里很详细的说明了这个问题。 我的目的只是要删除一行记录,可是这样使用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:
[url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=SELECT&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]SELECT[/url] [t0].[au_id], [t0].[au_lname], [t0].[au_fname], [t0].[phone], [t0].[address], [t0].[city], [t0].[state], [t0].[zip], [t0].[contract]
[url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=FROM&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]FROM[/url] [dbo].[authors] [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=AS&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]AS[/url] [t0]
[url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=WHERE&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]WHERE[/url] [t0].[au_id] [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=LIKE&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]LIKE[/url] @p0
-- @p0: Input VarChar (Size = 11; Prec = 0; Scale = 0) [111-11-111%]
-- Context: SqlProvider(Sql2000) Model: AttributedMetaModel Build: 3.5.21022.8
 
[url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=DELETE&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]DELETE[/url] [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=FROM&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]FROM[/url] [dbo].[authors] [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=WHERE&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]WHERE[/url] ([au_id] = @p0) [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=AND&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]AND[/url] ([au_lname] = @p1) [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=AND&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]AND[/url] ([au_fname] = @p2) [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=AND&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]AND[/url] ([phone] = @p3) [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=AND&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]AND[/url] ([address] = @p4) [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=AND&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]AND[/url] ([city] = @p5) [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=AND&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]AND[/url] ([state] = @p6) [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=AND&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]AND[/url] ([zip] = @p7) [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=AND&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]AND[/url] ([contract] = 1)
-- @p0: Input VarChar (Size = 11; Prec = 0; Scale = 0) [111-11-1111]
-- @p1: Input VarChar (Size = 3; Prec = 0; Scale = 0) [qqq]
-- @p2: Input VarChar (Size = 3; Prec = 0; Scale = 0) [qqq]
-- @p3: Input Char (Size = 12; Prec = 0; Scale = 0) [qqq         ]
-- @p4: Input VarChar (Size = 3; Prec = 0; Scale = 0) [qqq]
-- @p5: Input VarChar (Size = 3; Prec = 0; Scale = 0) [qqq]
-- @p6: Input Char (Size = 2; Prec = 0; Scale = 0) [qq]
-- @p7: Input Char (Size = 5; Prec = 0; Scale = 0) [22222]
-- Context: SqlProvider(Sql2000) Model: AttributedMetaModel Build: 3.5.21022.8
 
[url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=DELETE&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]DELETE[/url] [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=FROM&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]FROM[/url] [dbo].[authors] [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=WHERE&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]WHERE[/url] ([au_id] = @p0) [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=AND&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]AND[/url] ([au_lname] = @p1) [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=AND&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]AND[/url] ([au_fname] = @p2) [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=AND&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]AND[/url] ([phone] = @p3) [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=AND&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]AND[/url] ([address] = @p4) [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=AND&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]AND[/url] ([city] = @p5) [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=AND&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]AND[/url] ([state] = @p6) [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=AND&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]AND[/url] ([zip] = @p7) [url=http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=AND&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99]AND[/url] ([contract] = 1)
-- @p0: Input VarChar (Size = 11; Prec = 0; Scale = 0) [111-11-1112]
-- @p1: Input VarChar (Size = 3; Prec = 0; Scale = 0) [qqq]
-- @p2: Input VarChar (Size = 3; Prec = 0; Scale = 0) [qqq]
-- @p3: Input Char (Size = 12; Prec = 0; Scale = 0) [qqq         ]
-- @p4: Input VarChar (Size = 3; Prec = 0; Scale = 0) [qqq]
-- @p5: Input VarChar (Size = 3; Prec = 0; Scale = 0) [qqq]
-- @p6: Input Char (Size = 2; Prec = 0; Scale = 0) [qq]
-- @p7: Input Char (Size = 5; Prec = 0; Scale = 0) [22222]
很失望,和我期待的结果不一样。 在这个测试中,DataContent先把所有符合条件的记录全部取回来,再一个一个Delete。 如果要删除的有10000条记录的话,天都黑了... 这点,不得不说Linq to sql有点笨了。 3 解决? 只能绕个圈子了。 DataContext提供有ExecuteCommend方法,可能使用此方法直接执行SQL命令。比如这样:
Code 4:
using (PubsDataContext pubsContent = new PubsDataContext())
{
    pubsContent.Log = Console.Out;
    pubsContent.ExecuteCommand("delete from Authors where au_id like '111-11-111%'");
}
也可以通过DataContext.Connection取得当前的数据库连接,然后再通过DBCommend来提交自己的SQL语句, 或者写个存储过程来负责删除。 4 [b]LINQ[/b],语言级集成查询([b]L[/b]anguage [b]IN[/b]tegrated [b]Q[/b]uery) 明显,强在查询,删除就弱弱点 ;-)...
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部