0

我要疯了。我是 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 以某种方式检测到这个被忽略的删除重新插入以避免不必要的工作?

4

2 回答 2

1

那么不建议使用 ExecuteCommand 将 linq 与普通 sql 语句混合使用吗?

如果您打算依赖更改跟踪机制,则绝对不会。您的数据上下文将变得“陈旧”。

更新 如果您坚持使用“纯”L2S,所有插入/更新/删除都将转换为正确的 SQL。只要您使用一个 SubmitChanges 来完成它,它也将在一个事务中完成。所以它毕竟不是那么糟糕。您不能将它与 ExecuteCommand 混合使用,因为 L2S 不可能在不扫描整个数据库的情况下跟踪由存储过程引起的更改……这不是您想要的。

基本规则:为每个“工作单元”创建一个 DC,并且只为其执行一次 SubmitChanges。有了这个,你会很好地使用 L2s

于 2012-12-05T18:44:37.547 回答
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 很高兴听到您在这方面取得了进展:-)

一般建议:

  1. 除非您知道自己在做什么,否则避免将 ExecuteCommand 与 L2S 混合使用;ExecuteCommand的可能会改变 L2S 脚下的数据库状态并让您(当之无愧!)头疼!如果您不害怕这样的头痛,您可以尝试ExecuteCommand在 L2S 访问表之前删除行(更快,但您需要正确处理)。如果您害怕这样的头痛并且只想在 SQL 服务器上触发“删除”事件,只需SubmitChanges在问题代码中的 L2S“删除”之后执行一个操作。
  2. 您可以依靠 与数据库进行细粒度的 L2S 交互SubmitChanges,但从长远来看,最好意识到您获得了一个以全新方式与数据库交互的工具。L2S 试图变得聪明,这还不错。使用它为您带来优势!在这种特殊情况下,它为您节省了一些不必要的删除/插入操作,实际上优化了您的代码,而您无需做任何事情。试图变得那么聪明有错吗?是的,如果您单独考虑操作,如果您认为它试图做的只是使用代码操作的净效果更新数据库,则不。
于 2012-12-05T17:02:53.470 回答