1

I have a problem with entity framework code first six working so disconnected. The problem occurs when I want to mark an entity as modified, the entity has association properties loaded with a new instance of DbContext, to be more precise the source of my hit and then get the save.

 public List<Venta> Get(Expression<Func<Venta, bool>> predicate)
    {
        try
        {
            int num = 0;
            List<Venta> ventas = new List<Venta>();
            using (_context = new MyContext(MyContext.GetConnectionString()))
            {

                if (predicate == null)
                    ventas = _context.Ventas.Include("Mesa").Include("Usuario").Include("Pago").ToList();
                else
                    ventas = _context.Ventas.Include("Mesa").Include("Usuario").Include("Pago").Where(predicate).ToList();


             }

            //I use the other repo to load related entities
            UsuarioRepository userRepo = new UsuarioRepository();
            foreach (Venta item in ventas)
            {
                item.GetType().GetProperty("Usuario").SetValue(item, userRepo.Get(u => u.Id == item.UsuarioId).First(), null);
            }

            //I use the other repo to load related entities
            ProductoRepository prodRepo = new ProductoRepository();
            foreach (VentaProducto item in ventas.SelectMany(vta => vta.Detalle).ToList())
            {
                Producto p = prodRepo.Get(prod => item.ProductoId == prod.Id).First();
                item.GetType().GetProperty("Producto").SetValue(item, p, null);
            }

            ventas.ForEach(vta => vta.State = DomainEntityState.Unchanged);
            return ventas;
        }
        catch (Exception ex)
        {
            throw new Exception("Error al traer las Ventas", ex);
        }
    }

    public override int Save(Venta venta)
    {

        int saves = 0;
        EntityState state;
        EntityState stateProducto;



            //New Instance of the context without entities in the DbSet's
            using (MyContext context = new MyContext(MyContext.GetConnectionString()))
            {

                try
                {

                    if (venta.IsNewEntity) //Venta nueva
                    {
                        state = EntityState.Added;
                        stateProducto = EntityState.Modified;
                    }
                    else
                    {
                        state = EntityState.Modified;
                        stateProducto = EntityState.Modified;
                    }



                    //int usuarios = context.Usuarios.Local.Count; //I get 0
                    //int productos = context.Productos.Local.Count; //I get 0
                    //int ventasProductos = context.VentasProducto.Local.Count; // I get 0



                    venta.Usuario = null;
                    if (venta.Pago != null)
                        venta.Pago.Usuario = null;




                    if (venta.Pago != null)
                    {
                        EntityState estadoPago = context.GetEntityState(venta.Pago);
                    }

                    //HERE IS THE PROBLEM
                    context.SetEntityState(venta, state);



                    saves = context.SaveChanges();


                }

                catch (Exception ex)
                {
                    throw new Exception("Error al grabar la venta", ex);
                }
            }


        return saves;
    }

Finally I get the following error ....

Attaching an entity of type 'Jackie.Domain.Entities.Usuario' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.

The most strange is that if I load all entities with the same instance of context does not have that problem. It will be a bug? No longer think of anything more. Thank you all. Made with google translator.

  • The method appears to get cut in half, sorry I won the editor – ChristianDC Oct 14 '14 at 04:14
  • Please clean up and format your code. Remove useless comments and debugging code (like "//Only for watch the states" and other) - this code may even cause the problem. Also, why do you show this `Get` method? – Gert Arnold Oct 14 '14 at 07:29
  • Unlikely a bug in EF. You have either attemtpoed to load the same key twice in a context or you have attempted to load the same object instance in 2 contexts – phil soady Oct 14 '14 at 07:54
  • What I do is bring the entities with a context which is then discarded, and to save the changes using a new instance of the context. attach the two entities with the same PK is not the problem since the context that I use to record the data is a new instance. Thank you all for your help. – ChristianDC Oct 14 '14 at 13:13
  • phil that is the question, I avoid having 2 times the same entity in the context but just shoot me the problem is more the status of entity is dettached. Thanks and regards. – ChristianDC Oct 14 '14 at 15:34
  • gert, We show that get in the way institutions bring the problem kicks me if I bring absolutely all entities with the same context instance does not throw me the exception but not the scenario I'm needing, craziest thing is that it seems like EF to keep in memory the state of x entities even when working in isolation from the context using the pattern – ChristianDC Oct 14 '14 at 15:37
  • You might have a look at my answer on [ASP.NET MVC - Attaching an entity of type 'MODELNAME' failed because another entity of the same type already has the same primary key value](http://stackoverflow.com/questions/23201907/asp-net-mvc-attaching-an-entity-of-type-modelname-failed-because-another-ent/39557606#39557606). – Murat Yıldız Sep 18 '16 at 12:37

1 Answers1

0

There are (at least) two Usuario properties in the object graph - venta.Usuario and venta.Pago.Usuario. By attaching the venta entity, the entity objects in these two Usuario properties will be attached as Unmodified. If these two properties hold two different instances of the Usuario class with the same PK value, when the second is attached it will throw the error you received. This seems quite possible as you're loading navigation properties via different instances of the context with some eager loading thrown into the mix.

Break at the call to context.SetEntityState(venta, state) and see if those two Usuario objects are actually the same instance or two different instances with the same PK value(s).

Moho
  • 15,457
  • 1
  • 30
  • 31
  • --This seems quite possible as you're loading navigation properties via different instances of the context with some eager loading thrown into the mix. <-- yes, that is, but i set null in both usuario properties because i not want save usuario in this repository. – ChristianDC Oct 14 '14 at 15:13
  • -Break at the call to context.SetEntityState(venta,state) and see if those two Usuario objects are actually the same instance or two different instances with the same PK value.< I watch this and the dbset usuarios.local.count = 0.Truth is driving me crazy, when I look at the state of the user input is equals detached. I do not have the exception when I load all objects with the same instance of the context, ie loading all entities with the same context in the repository sales.Again Ithank you for your goodvibes to help me. If you want I can attach all the source since the application is small. – ChristianDC Oct 14 '14 at 15:20
  • Here is the cs file with the Venta Repository , https://www.dropbox.com/s/gekegrqu19hrsk5/VentaRepository.cs?dl=0 – ChristianDC Oct 14 '14 at 15:26
  • Are you certain there are no other instances of `Usuario` in the object graph for the `Venta` entities? – Moho Oct 14 '14 at 15:47
  • and what are your implementations of `context.GetEntityState` and `context.SetEntityState`? – Moho Oct 14 '14 at 15:48
  • Moho here is the code public EntityState GetEntityState(object entity) { return this.Entry(entity).State; } public void SetEntityState(object entity, EntityState state) { this.Entry(entity).State = state; } – ChristianDC Oct 14 '14 at 15:52
  • Moho , yes i am sure watch this lines venta.Usuario = null; if (venta.Pago != null) venta.Pago.Usuario = null; – ChristianDC Oct 14 '14 at 15:54
  • because of this the users are out of context but still throws me the exception, here goes the logic of the property public Usuario Usuario { get { return _vendedor; } set { _vendedor = value; if (value != null) _idVendedor = value.Id; } } – ChristianDC Oct 14 '14 at 15:55