实体框架-在没有事务的情况下强制提交

本文关键字:情况下 提交 事务 框架 实体 | 更新日期: 2023-09-27 17:58:26

我有一个循环,看起来有点像:

CountsToReport = rep.Counts_Get().Where(x => x.Status == "Completed");
foreach (var count in CountsToReport.ToList())
{
    //do some stuff
    //send an email
    count.Status = "Reported";
    rep.SaveChanges();
}

其中"rep"是围绕EF上下文的存储库包装器。

当这种情况运行时,不幸的电子邮件收件人会收到大量垃圾邮件,因为SaveChanges调用实际上并没有提交更改,所以循环不断获得相同的计数,发送电子邮件,并将其标记为"已报告",但实际上并没有保存更改。

如果停止循环并重新启动代码,则更改将成功保存。您可以通过逐步执行代码来确认这种情况:C#中的EF对象会更改其状态,但SQL中的底层数据不会更改。

我推测这是因为SaveChanges实际上并没有提交事务——它只是将数据标记为已更改,为事务结束做好准备。但是,我们没有在数据库中的任何其他地方使用事务,并且为这个用例更改存储库会有点麻烦。

有没有其他方法可以迫使EF做出这一改变,逃离我无尽的厄运循环?还是我弄错了原因?

编辑:把这个放在存储库中,并调用它而不是SaveChanges他的修复程序:

public void SaveWithTransaction()
{
    using (var transaction = new System.Transactions.TransactionScope())
    {
        db.SaveChanges();
        transaction.Complete();
    }
}

但它看起来很丑陋。仍然有兴趣知道是否还有其他办法。

编辑:这是骗人的。看起来这又是一个旧的添加/修改问题。将对象标记为已修改似乎有帮助。

实体框架-在没有事务的情况下强制提交

CountsToReport中的实体很可能与上下文分离。因此,ChangeTracker不仅没有看到对Count进行任何更改,而且对实体一无所知。

解决问题:

  • 遍历CountsToReport的集合
  • 将每个实体附加回上下文,类似于db.Counts.Attach(count)
  • 修改计数。状态和调用数据库。SaveChanges()

像这样:

foreach (var count in CountsToReport.ToList())
{
    //do some stuff
    //send an email
    rep.Counts.Attach(count);
    count.Status = "Reported";
    rep.SaveChanges();
}

有关实体状态以及如何处理这些状态的更多信息,请查看以下链接:http://msdn.microsoft.com/en-us/data/jj592676.aspx