none
Error de Borrado con Entity Framework RRS feed

  • Pregunta

  • Tengo un problema al borrar un elemento de una tabla con Entity Framework.

    Tengo una capa de acceso a datos y otra con una logica de negocio. La capa de acceso a datos es la que crea el contexto de corta duración para el borrado. EL código es el siguiente (es una clase genérica):

    public bool Delete(T item)
            {
                using (K context = new K())
                {
                    if (item.EntityKey == null)
                        item.EntityKey = context.CreateEntityKey(mPredicate, item);
                    context.Attach(item);
                    
    
                    try
                    {                    
                        context.DeleteObject(item);
                        context.SaveChanges();
                        return true;
                    }
                    catch (OptimisticConcurrencyException)
                    {
                        context.Refresh(RefreshMode.ClientWins, item);
                        context.SaveChanges();
                        return true;
                    }
                    catch (UpdateException)
                    {
                        // TODO: Pendiente
                        return false;
                    }
                }
            }
    El error salta en la ejecución de la sentencia Attach al exisitir ya el elemento en el contexto:

    [InvalidOperationException: Varias instancias de IEntityChangeTracker no pueden hacer referencia a un objeto de entidad.]
    Como me supongo es debido a que existe ya en el contexto y no es posible adjuntarlo al mismo de nuevo.
    Luego me di cuenta que solo haría falta unirlo al contexto en caso de que el objeto se acabara de crear en el contexto pero no se hubiera persistido aún, pero entonces el error es otro.

    Se produce al ejecutar DeleteObject y se produce la siguiente excepcion:
    [InvalidOperationException: El objeto no se puede eliminar porque se encontró en ObjectStateManager.]
    El objeto se recupera en la logica de negocio mediante una consulta (que crea su propio contexto de vida corta).

    public MedioComunicacion GetMedioComunicacionById(int _idMedio)
            {
                List<MedioComunicacion> retorno = MedioComunicacionDataAccess.GetWithFilter(m => m.IdMedioComunicacion == _idMedio);
                if (retorno.Count > 0) return retorno.First<MedioComunicacion>();
                else return null;
            }
    Y el código GetWithFilter que hace la consulta:
    public List<T> GetWithFilter(Expression<Func<T, bool>> filter)
            {
                using (K context = new K())
                {
                    ObjectQuery<T> query = CreateQuery(context);
                    return query.Where(filter).ToList<T>();
                }
            }


    Alguna ayuda o idea?
    martes, 5 de enero de 2010 12:30

Todas las respuestas