mvc - Código de Entity Framework First-Sin método Detach() en DbContext
entity framework example (4)
Me pregunto por qué no hay un método Detach en el objeto DbContext como lo hay para ObjectContext. Solo puedo asumir que esta omisión fue intencional, pero me cuesta entender por qué. Necesito poder separar y volver a unir entidades (por ejemplo, poner el caché en un proyecto ASP.NET). Sin embargo, como no puedo separar una entidad, cuando intento adjuntar una entidad asociada a un contexto anterior, aparece la excepción "Un objeto de entidad no puede ser referenciado por varias instancias de IEntityChangeTracker".
¿Cuál es la guía aquí? ¿Me estoy perdiendo de algo?
DbContext utiliza un ObjectContext internamente y el equipo de EF lo pone a disposición como una propiedad protegida en caso de que alguna vez deba bajar al API de nivel inferior y suena como este es el caso aquí, para que pueda usar o exponer la funcionalidad requerida de un derivado DbContext:
public class YourContext : DbContext
{
public void Detach(object entity)
{
ObjectContext.Detach(entity);
}
}
Luego puede llamar a este método desde su controlador para separar una entidad.
Alternativamente, puedes cambiarlo incluso para tener una API más rica:
public class YourContext : DbContext
{
public void ChangeObjectState(object entity, EntityState entityState)
{
ObjectContext.ObjectStateManager.ChangeObjectState(entity, entityState);
}
}
Así es como se ve DbContext a partir de los metadatos:
public class DbContext : IDisposable
{
protected System.Data.Objects.ObjectContext ObjectContext { get; }
...
}
Normalmente extiendo la clase base (hereda de DbContext) con la propiedad:
public class MyDbContext : DbContext
{
public ObjectContext ThisObjectContext
{
get
{
return ((IObjectContextAdapter)this).ObjectContext;
}
}
}
más tarde puede usar esta propiedad para una variedad de cosas útiles ... como Detach :)
Para las personas que puedan tropezar con esta pregunta, a partir de CTP5, ahora necesita escribir
((IObjectContextAdapter)context).ObjectContext
para llegar a ObjectContext.
EF: CF 4.1 RC1 y EF: CF 4.1 RTW tienen el mismo IObjectContextAdapter explícitamente implementado:
public static class DbContextExtensions
{
public static void Detach(this System.Data.Entity.DbContext context, object entity)
{
((System.Data.Entity.Infrastructure.IObjectContextAdapter)context).ObjectContext.Detach(entity);
}
}
Microsoft decidió que "Detach es una tecnología demasiado avanzada y debería estar oculta". En mi humilde opinión, el hombre que inventó esto debe recibir un disparo, porque si agrega una nueva entidad, es difícil simplemente eliminarla sin realizar cambios en db (puede manipular con DbEntityEntry, pero esa es otra historia).
Editar 4 años después:
Con EF6 (de alguna manera me salté EF5 :)) ya no necesita detach()
, porque eliminar la entrada recién agregada no genera delete from [table] where [Id] = 0
como en EF4 - puede simplemente llamar a mySet.Remove(myFreshlyCreatedAndAddedEntity)
y todo estará bien.