【问题标题】:Entities may have been modified or deleted since entities were loaded. Error during transaction自加载实体后,实体可能已被修改或删除。交易时出错
【发布时间】:2016-03-20 20:13:15
【问题描述】:

在执行以下代码期间,我收到消息

存储更新、插入或删除语句影响了意外数量的行 (0)。自加载实体后,实体可能已被修改或删除。刷新 ObjectStateManager 条目。

这里有很多这样的情况,但我没有找到解决问题的方法。

这只会发生在我身上,因为我在一个事务中运行了两次 _db.SaveChanges()_db 是我的数据库上下文对象),我必须这样做,因为我需要它按顺序提供给我的生成 ID继续代码。

如果有人可以帮助我,我将不胜感激。另外,如果您知道没有两个_db.SaveChanges() 的方法或处理交易的不同方法,我欢迎您展示它。

using (var trans = _db.Database.BeginTransaction())
{
    try
    {
        var f = cbxFornecedor.SelectedItem as Fornecedor;
        var c = new Compra
                {
                    CompraId = compra.CompraId,
                    DataCompra = dtpDataCompra.Value,
                    ListaProdutos = new List<ListaProdutos>(),
                    Fornecedor = f,
                    Referencia = tbxReferencia.Text,
                    Situacao = rbtEntregue.Checked
                };

        _db.Compras.Add(c);
        _db.SaveChanges();

        foreach (var cada in _itens)
            c.ListaProdutos.Add(new ListaProdutos
                    {
                        Compra = c,
                        CompraId = c.CompraId,
                        Produto = cada.ProdutoClasse,
                        ProdutoId = cada.ProdutoClasse.ProdutoId,
                        Valor = cada.ValorTotal,
                        Quantidade = cada.Quantidade,
                    });

        foreach (var cada in c.ListaProdutos)
            if (_db.ListaProdutos.Find(cada.CompraId, cada.ProdutoId) != null)
                _db.Entry(cada).State = EntityState.Modified;
            else
                _db.ListaProdutos.Add(cada);

        _db.Entry(c).State = EntityState.Modified;
        _db.SaveChanges();

        trans.Commit();
    }
    catch (Exception ex)
    {
        trans.Rollback();
        MessageBox.Show(this, ex.Message, @"Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

而且,为了清楚起见,我知道我的问题在于交易存在这一事实。我尝试删除它并且它有效。另外,如果我取出第二个_db.SaveChanges(),它也可以。

该异常只在第二个_db.SaveChanges()中抛出,并且只有在被事务块包围的情况下。

【问题讨论】:

  • CompraId 属性是否为 Compra 生成了 ID?如果是,那为什么在创建new Compra { CompraId = compra.CompraId; 时分配它?
  • 好吧,我也会修改代码来处理更新,但是现在我可以保证那里的代码总是0。

标签: entity-framework dbcontext


【解决方案1】:

这不是您问题的直接答案,但可能会有所帮助。

您不需要为new ListaProdutos 指定 Compra 和 CompraId,因为 EF 足够聪明,可以弄清楚。此外,您似乎不需要 _db.ListaProdutos.Find(cada.CompraId, cada.ProdutoId) != null 检查,因为 cada.CompraId - 是新 ID,此时它不能在数据库中。此外,您不需要_db.ListaProdutos.Add(cada);,因为您正在添加此记录的 EF 已经是新的。可以试试下一个代码吗?

var f = cbxFornecedor.SelectedItem as Fornecedor;
var c = new Compra
    {
        DataCompra = dtpDataCompra.Value,
        ListaProdutos = new List<ListaProdutos>(),
        Fornecedor = f,
        Referencia = tbxReferencia.Text,
        Situacao = rbtEntregue.Checked
    };

_db.Compras.Add(c); 

foreach (var cada in _itens)
    c.ListaProdutos.Add(new ListaProdutos
        {
            Produto = cada.ProdutoClasse,
            ProdutoId = cada.ProdutoClasse.ProdutoId,
            Valor = cada.ValorTotal,
            Quantidade = cada.Quantidade,
        });
_db.SaveChanges();

【讨论】:

  • 工作得像个有魅力的人。我实际上可以删除事务块,因为它只有一个_db.SaveChanges(),但它也可以使用它。正如我上面所说,我正在寻找问题的任何解决方案,而不仅仅是我正在接近的解决方案,所以我将你标记为答案。谢谢!
猜你喜欢
  • 2013-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-20
  • 1970-01-01
相关资源
最近更新 更多