【问题标题】:Linq To SQL Delete + Insert best practiceLinq To SQL 删除 + 插入最佳实践
【发布时间】:2016-01-27 21:02:57
【问题描述】:

如标题所述,我需要执行删除 + 插入,我会这样做:

 context.DeleteAllOnSubmit ( deleteQuery ) ;

 foreach ( var entry in entries ) 
      contex.InsertOnSubmit ( entry ) ;

 context.SubmitChanges();

正如在那篇文章中所写: Linq to SQL: execution order when calling SubmitChanges()

我读到删除操作是最后一个应用的,但目前我看到我的逻辑工作(我确信删除+插入每天发生几十次)。 我需要的是了解帖子是否错误或我的逻辑出于某种原因(将 linq 中的检查标志更新为 sql 数据模型?)只是幸运并避免麻烦。

之后我想知道当记录基数发生变化时进行“更新”的更好模式是什么。 我的意思是在我的表中有一个标识实体的主键(一个实体有许多记录)和一个标识同一实体(子实体)中每条记录的子键。 我需要重新生成(因为可能会插入、编辑或删除某些子实体),所以我使用 delete + insert(在我写入 DB 的消息形式中,仅包含存在的实体和子实体,而不是已删除的实体和子实体)。

EG:

 ID     SubID    Data
 1      1_0      Father      
 2      2_0      Father
 2      2_1      Child 1
 3      3_0      Father
 3      3_1      Child 1
 3      3_2      Child 2

我无法控制或控制表格(以及其中的数据格式)或消息(我用来写入或删除上面显示的表格)。

【问题讨论】:

  • 你说的是交易吗?我发布您使用TransactionScope 引用已接受的答案。
  • 你能有一个不是自动生成的唯一键吗?
  • @teovankot 我会避免交易,因为我的是批处理操作(每个更新的巨大序列都用 xml 消息发送给我)所以我想避免打开和关闭很多交易.
  • @AnilKumar:不,我无法控制表格(我无法更改它们的格式),也无法更新、插入或删除我收到的消息
  • 亲爱的:如果我链接的问题是正确的并且删除操作是最后一次应用在 SQL Server 上,那么我很感兴趣的一件事是指出。如果答案是肯定的,那么我想知道为什么目前我的程序似乎运行良好

标签: c# sql-server linq


【解决方案1】:

我读到删除操作是最后一个应用的,但目前我看到我的逻辑工作(我确信删除+插入每天发生几十次)。 我需要了解帖子是否错误或我的逻辑并且出于某种原因(将 linq 中的检查标志更新为 sql 数据模型?)只是幸运并避免了麻烦。

帖子正确,删除后实际删除。

您的代码按照设计运行,这不是偶然的。

它实际上加载了所有要删除的记录,然后将其全部删除。这终于发生了。

这永远不会失败,也不会删除错误的记录,但是它有性能问题,你可以参考很好的msdn article这个

无论您对对象进行了多少更改,都只会对内存中的副本进行更改。您没有对数据库中的实际数据进行任何更改。在您明确调用 DataContext 上的 SubmitChanges 之前,您的更改不会传输到服务器。

当您进行此调用时,DataContext 会尝试将您的更改转换为等效的 SQL 命令。您可以使用自己的自定义逻辑来覆盖这些操作,但提交的顺序由 DataContext 的服务(称为更改处理器)进行编排。

事件顺序如下:参考msdn

  1. 当您调用 SubmitChanges 时,LINQ to SQL 会检查一组已知对象以确定是否已将新实例附加到它们。如果有,则将这些新实例添加到跟踪对象集中。 这就是我们一开始说插入的原因

  2. 所有具有挂起更改的对象都根据它们之间的依赖关系排序为一系列对象。其更改依赖于其他对象的对象在它们的依赖关系之后排序。 然后更新

更新删除完成后

在传输任何实际更改之前,LINQ to SQL 立即启动一个事务来封装一系列单独的命令。

对对象的更改被一一转换为 SQL 命令并发送到服务器。

此时,数据库检测到的任何错误都会导致提交过程停止,并引发异常。

对数据库的所有更改都将回滚,就好像从未发生过提交一样。 DataContext 仍然有所有更改的完整记录

【讨论】:

  • 我应用了再生逻辑,所以在我的示例表中,我可以发送另一条消息,其中包含 ID 1 的 SubID 1_0 和 SubID 1_1。我的逻辑是,删除所有 id 为 1 的条目,然后插入(1,1_0)和插入(1,1_1)。在那种情况下,我预计会发生主键违规(因为它会首先尝试插入然后删除与我期望相反的内容),但我没有在我的系统中记录该错误。在消息之后更重要的是我在桌子上有两条记录。如果删除将是最后一次操作,我预计 0 条记录
  • 您要删除一条记录,然后插入一条具有相同键的新记录?只更新它有什么问题。
  • 不,我有一条消息只告诉我(条目 1 子条目 1_0 和子条目 1_1)。要使用更新逻辑,我需要检查消息中的每个条目是否存在(更新)或是否需要插入。之后,我需要检查表中是否有比消息中更多的条目,然后删除它们。这很复杂,所以我采用了再生方法。
  • 感谢我更好地了解了 DataContext 的生命周期。但我不清楚为什么我的逻辑似乎有效。我的意思是,现在我很清楚我的方法是错误的,但现在改变是一项巨大的努力(我从 12 月开始投入生产),我想知道我是否可以考虑可靠,即使不是最优的,或者有一天可以停止工作
  • @Skary,如果您有访问权限,您能否跟踪 SQL Profiler 中的 sql 语句和序列。我相信还有更多的东西,你的删除语句是如何形成的。参考weblogs.asp.net/zeeshanhirani/…stackoverflow.com/questions/729774/…
猜你喜欢
  • 1970-01-01
  • 2011-02-16
  • 2010-12-31
  • 1970-01-01
  • 2018-01-30
  • 2010-09-08
  • 2010-10-10
  • 1970-01-01
  • 2011-05-05
相关资源
最近更新 更多