DbContext SaveChanges 语句执行顺序

发布于 2024-12-03 18:55:15 字数 656 浏览 0 评论 0原文

我有一个表,该表在带有序号列的表上有唯一索引。例如,该表将具有以下列:

TableId、ID1、ID2、Ordinal

唯一索引跨 ID1、ID2、Ordinal 列。

我遇到的问题是,当从数据库中删除记录时,我会对序数重新排序,以便它们再次按顺序排列。我的删除函数将如下所示:

    public void Delete(int id)
    {
        var tableObject = Context.TableObject.Find(id);
        Context.TableObject.Remove(tableObject);
        ResequenceOrdinalsAfterDelete(tableObject);
    }

问题是,当我调用 Context.SaveChanges() 时,它会破坏唯一索引,因为它似乎以与传递的顺序不同的顺序执行语句。例如,会发生以下情况:

  1. 对序数重新排序
  2. 删除记录

而不是:

  1. 删除记录
  2. 对序数重新排序

这是 EF 的正确行为吗?如果是,是否有办法覆盖此行为以强制执行顺序?

如果我没有正确解释这一点,请告诉我......

I have a table that has a unique index on a table with an Ordinal column. So for example the table will have the following columns:

TableId, ID1, ID2, Ordinal

The unique index is across the columns ID1, ID2, Ordinal.

The problem I have is that when deleting a record from the database I then resequence the ordinals so that they are sequential again. My delete function will look like this:

    public void Delete(int id)
    {
        var tableObject = Context.TableObject.Find(id);
        Context.TableObject.Remove(tableObject);
        ResequenceOrdinalsAfterDelete(tableObject);
    }

The issue is that when I call Context.SaveChanges() it breaks the unique index as it seems to execute the statements in a different order than they were passed. For example the following happens:

  1. Resequence the Ordinals
  2. Delete the record

Instead of:

  1. Delete the record
  2. Resequence the Ordinals

Is this the correct behaviour of EF? And if it is, is there a way of overriding this behaviour to force the order of execution?

If I haven't explained this properly, please let me know...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

人间☆小暴躁 2024-12-10 18:55:15

命令顺序完全由 EF 控制。影响顺序的唯一方法是为每个操作使用单独的 SaveChanges:

public void Delete(int id)
{
    var tableObject = Context.TableObject.Find(id);
    Context.TableObject.Remove(tableObject);
    Context.SaveChanges();
    ResequenceOrdinalsAfterDelete(tableObject);
    Context.SaveChanges();
}

您还应该在手动创建的事务中运行该代码以确保原子性 (=> TransactionScope)。

但最好的解决方案可能是使用存储过程,因为重新排序必须将所有受影响的记录从数据库提取到应用程序,更改它们的序号并将它们一一保存回数据库。

顺便提一句。用数据库异味来做到这一点。 “序数”序列中存在间隙有什么问题?

Order of commands is completely under control of EF. The only way how you can affect the order is using separate SaveChanges for every operation:

public void Delete(int id)
{
    var tableObject = Context.TableObject.Find(id);
    Context.TableObject.Remove(tableObject);
    Context.SaveChanges();
    ResequenceOrdinalsAfterDelete(tableObject);
    Context.SaveChanges();
}

You should also run that code in manually created transaction to ensure atomicity (=> TransactionScope).

But the best solution would probably be using stored procedure because your resequencing have to pull all affected records from the database to your application, change their ordinal and save them back to the database one by one.

Btw. doing this with database smells. What is the problem with having a gap in your "ordinal" sequence?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文