我正在为此疯狂。我是linq to sql的新手,并没有完全掌握linq的更改跟踪概念。我有一种情况,我必须在单个DataContext中做大量的db东西。我注意到许多奇怪的东西,如:
//Control flows to this statement, but I dont see
//corresponding sql generated in the log.
//However if I instead change it to db.ExecuteCommand("delete from mytable")
//that shows up fine in the log
db.mytable.deleteAllOnSubmit(db.mytable);
这只是故事的一部分。但是我想知道是否会出现没有生成正确sql的情况?可能有一种可能性,我试图删除表中的所有行,但稍后,我尝试再次插入相同的行,linq以某种方式检测到这个忽略的delete-reinsert以避免不必要的工作?
答案 0 :(得分:1)
您必须记住,deleteAllOnSubmit
等操作不会转换为SQL并在现场执行。
ITable.DeleteAllOnSubmit方法: 将集合中的所有实体置于挂起删除状态。
请参阅:http://msdn.microsoft.com/en-us/library/system.data.linq.itable.deleteallonsubmit.aspx
在您执行以下操作之前不会删除:
db.SubmitChanges();
更新1:
如果您的表为空,则不会发生删除语句。此外,SubmitChanges
允许在您的特定场景中尝试变得聪明,但如果您有触发器,您认为会被执行,您会感到失望。如果你有删除/插入触发器,你可能想要考虑在LINQ'删除'之后有一个SubmitChanges。
DataContext.SubmitChanges方法:计算要插入,更新或删除的修改对象集,并执行相应的命令以实现对数据库的更改。
http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.submitchanges.aspx
注意:此更新是在OP检查并确认在调用SubmitChanges()
时表格为空时进行的。稍后,OP检查并验证,当从表中删除数据时,也会发生这种情况,只是用相同的数据替换。
更新2:
@Brian很高兴听到你在这方面取得进展:-)
一般建议:
ExecuteCommand
可能会改变L2S脚下的数据库状态并给你(当之无愧! )头痛!如果您不担心此类问题,可以在L2S访问表之前尝试使用ExecuteCommand
删除行(更快但您需要正确)。如果您害怕这些令人头疼的问题并且只想在SQL服务器上触发'on delete'事件,那么只需在问题代码中的L2S“删除”之后执行SubmitChanges
。 SubmitChanges
的数据库进行细粒度的L2S交互,但从长远来看,您会更好地意识到您将获得一个全新的数据库交互工具办法。 L2S试图变得聪明,这也不错。使用它对您有利!在这种特殊情况下,它为您节省了一些不必要的删除/插入操作,实际上是优化代码,而无需您执行任何操作。试着变得聪明是不对的?是的,如果你单独考虑操作,如果你认为它所做的一切都是用代码的动作的净效果来更新数据库,那就没有。 答案 1 :(得分:1)
那么不建议将linq与普通的sql语句混合使用 使用ExecuteCommand?
如果您打算依赖变更跟踪机制,请定义。您的datacontext将变为“陈旧”。
<强>更新强> 如果您坚持使用'纯'L2S,则所有插入/更新/删除都将转换为正确的SQL。只要您使用一个SubmitChanges执行此操作,它也将在一个事务中完成。所以它毕竟不是那么糟糕。您不能将它与ExecuteCommand混合,因为L2S无法跟踪由例如存储过程导致的更改而不扫描整个数据库...不是您想要的。
基本规则:为每个“工作单元”创建一个DC,并为其执行一次SubmitChanges。有了这个,你可以使用L2