Context trying to delete the same record twice

Asked

Viewed 146 times

0

I’m having a problem, actually it must be the same lack of knowledge, at the time of deleting a record using Entity Framework 6.

When I try to delete a record that cannot be deleted because it has references, it gives the following error:

inserir a descrição da imagem aqui inserir a descrição da imagem aqui

So far, so good.

Ai I will try to delete another record, which I am sure has no reference, and it gives the same error, in fact is trying to delete again the previous record.

If I exit the screen and enter again then I can delete the record normally as long as I don’t try to delete another one before it generates the error.

Does anyone have a light? VLW

EDIT: Follow my code to better understand:

Screen signature:

private readonly ICategoriaAppService _categoriaApp;
private CategoriaViewModel _categoria;

public FormCategorias(ICategoriaAppService categoriaAppService)
{
    _categoriaApp = categoriaAppService;
    InitializeComponent();
}

Method to exclude:

private void btnExcluir_Click(object sender, EventArgs e)
{
    DialogResult resposta = MessageBox.Show("Deseja excluir este registro?", "Excluir", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
    switch (resposta)
    {
        case DialogResult.Yes:
            var categoriaDomain = _categoriaApp.ObtemPeloID(_categoria.Numero_Categoria);
            _categoriaApp.Excluir(categoriaDomain);
            MessageBox.Show("Registro excluido com sucesso");
            break;
        case DialogResult.No:
            break;
    }
}

Appservice:

private readonly ICategoriaService _categoriaService;

public CategoriaAppService(ICategoriaService categoriaService) : base(categoriaService)
{
    _categoriaService = categoriaService;
}

public void Excluir(TEntity obj)
{
    _serviceBase.Remove(obj);
}

Service:

public class ServiceBase<TEntity> : IDisposable, IServiceBase<TEntity> where TEntity : class
{
    protected ControleEstoqueContexto Db = new ControleEstoqueContexto();

    public ServiceBase()
    {
        Db.Configuration.AutoDetectChangesEnabled = false;
    }

    public virtual void Remove(TEntity obj)
    {
        try
        {
            Db.Set<TEntity>().Remove(obj);
            Db.SaveChanges();
        }
        catch (Exception e)
        {
            Db.Dispose();
            Db = new ControleEstoqueContexto();
            throw e;
        }
    }

    //ETC
}

EDIT 2: Solved by putting Try catch and redoing Db.Context. Above changed code.

2 answers

1


Putting your code makes it easier to point out the problem.

What seems to be happening to you is this.

Contexto.Objetos.Remove(instancia1);
Contexto.SaveChanges();

Error... After the mistake you make:

Contexto.Objetos.Remove(instancia2);
Contexto.SaveChanges();

Whereas instancia2 has no key. Only the context still has the "order" to exclude the instancia1. And he tries to delete both instances. So he makes a mistake in trying to delete 1. Got it? After the error redoes the context, or sees the best logic for you (not in your code it is difficult to say what it would be) and tests.

When you close the screen and open again the context is redone, so when you redo only the Remove(instancia2) it works.

UPDATING

You in the form load inject an instance of the (very cool) context. During the execution of the events you will use the same context.

First thing I would do is treat the mistake, or make it delete the relationship or not even let it get there. That’s what I suggest.

If it’s not possible, the best thing to do is to create the new one, but don’t forget to make one Dispose() of the current.

Here has another response suggesting also the new instead of changing the status of the object that is to be deleted.

  • Ricardo, thank you. I edited the question with the code. But I understood what you meant. When you say to redo the context is to put a "new Context" when the error occurs?

  • I edited the answer, I think it is now more complete, not fail to see the link I put, I hope I answered you.

  • Ricardo, Vlw. As for dealing with the mistake, I will certainly do that. I think it’s better too. However, you never know, another mistake may occur, and I need to leave it as best I can. I tried to give Db.Dispose(); and then Db = new Controleestoquecontext(); right after the rollback. It even works, but does not effect exclusion in the bank. I even looked through the SQL trace, it even redoes the queries to load the context again, but nothing was changed. Just to be clear, I put a transaction on the exclusion just to test this.

  • I did not understand if in the end everything went well or not rsrs. Edit the question there with the new code and the result, if it did not work.

  • I edited there, I put one of the attempts. Yes, it is not an error, but also not effective the deletion of the record in the bank, rsss. I tried to re-load the entity back to the state for Unchanged, but nothing solved.

  • From your comment you made a Begin in the transaction, sent saved, checked in the bank, did not see the exclusion and gave rollback, was that it? Pq se der Begin vc will not see anything in the bank until commit.

  • Rsss, my bad. In the hurry I forgot the commit. Brigadão Ricardo. I will change the question to leave as it was at the end. Vlw

Show 2 more comments

0

In its place, I would not inject into the form a service, but rather a context. A tutorial from Microsoft goes exactly in this line.

This is another problem of the highlighted context. You load the data using a context and try the persistence using another context.

  • Hello Gypsy. To my understanding the tutorial is not focused on the EF itself. But, even so, would not it be all at the front? Example, at the time of inclusion of a record, I have some business logic to do, and make other inclusions depending on this logic, including handling everything within transaction. That sort of thing shouldn’t stay in my domain?

  • First make everything work on the Front, then you separate by layers. It is simpler for you to understand the mistakes from now on.

  • I’ll do it. VLW.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.