martes, 3 de julio de 2012

Entity Framework y el borrado de entidades (I)

A la hora de borrar entidades en Entity Framework nos damos cuenta que podemos actuar de dos maneras diferentes sobre todo si tenemos en cuenta factores como el número de consultas que tenemos que lanzar contra nuestra base de datos.

Borrado de entidades por la clave primaria
Quizás es la forma más natural de realizar un borrado aunque no por ello es la única. Supongamos que tenemos la siguiente entidad POCO con la cual hemos montado nuestra base de datos a través de Code First.
public class Bar
{
  public int IdBar { get; set; }
  public string Description { get; set; }
  public int IdState { get; set; }
}
El código para borrar una entidad por su clave primera podría ser algo así
private void DeleteByID(int idBar)
{
  using (DataContext context = new DataContext()) {
    Bar bar = context.Bar.Where(m => m.IdBar == idBar).SingleOrDefault();
    context.Bar.Remove(bar);
    context.SaveChanges();
  }
}
¿Sencillo verdad? La verdad es que si, aunque si somos un poco curiosos o simplemente sabemos lo que estamos haciendo y usamos el SQL Server Profiler veremos que la ejecución de ese código tan simple genera estas dos consultas
exec sp_executesql N'SELECT TOP (2) 
[Extent1].[IdBar] AS [IdBar], 
[Extent1].[Description] AS [Description], 
[Extent1].[IdState] AS [IdState]
FROM [dbo].[Bar] AS [Extent1]
WHERE [Extent1].[IdBar] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=1
exec sp_executesql N'delete [dbo].[Bar]
where ([IdBar] = @0)',N'@0 int',@0=1
O sea, que estamos lanzando dos consultas contra nuestra base de datos para simplemente hacer un borrado. Esto desde mi punto de vista es un poco absurdo, aunque menos mal que con un pequeño truco podemos resolver este pequeño inconveniente. El truco consiste en adjuntar a nuestro contexto una entidad con la clave que queramos borrar, luego la borramos y grabamos los cambios. Con esto se lanzará la consulta de borrado con la información de la clave que deseamos borrar. El código para esto es el siguiente
private void DeleteByID(int idBar)
{
  using (DataContext context = new DataContext())
  {
    Bar bar = new Bar() { IdBar = idBar };
    context.Bar.Attach(bar);
    context.Bar.Remove(bar);
    context.SaveChanges();
  }
}
Si usamos el SQL Profiler con este método veremos que tan solo se ejecuta esta consulta
exec sp_executesql N'delete [dbo].[Bar]
where ([IdBar] = @0)',N'@0 int',@0=1
Como vemos, con un pequeño cambio hemos podido resolver de una manera fácil el problema de rendimiento que podríamos tener si hacemos muchos borrados en nuestra aplicación.

En el próximo artículo trataré el borrado de registros cuando no estamos borrando por la clave primaria y donde una vez más el número de accesos a la base de datos puede ser un factor muy importante a tener en cuenta.

Happy codding!

No hay comentarios:

Publicar un comentario