Este post presume que você possui algum conhecimento acerca do EntityFramework
É muito comum vermos colunas como IsDeleted ou IsActive em alguns modelos de dados. Essas colunas servem para indicar o status dos registros de uma determinada tabela.
Na maior parte do tempo queremos retornar registros onde IsActive é true e IsDeleted é false, ou seja, em várias partes do código teremos algo similar a isso:
.Where(w => w.IsActive) // Retorna os registros ativos de uma determinada tabela
.Where(w => !w.IsDeleted) // Retorna os registros que não foram deletados de uma determinada tabela
É um saco ter que fazer essas verificações toda hora e é ai que entra o Global Query Filters que é um forma de definir um filtro global aplicado aos Tipos de Entidade no modelo de metadados (normalmente,OnModelCreating). Esses filtros são aplicados automaticamente em qualquer consulta LINQ que envolva esses Tipos de Entidade.
Hands-On
Criando o projeto
dotnet new console -n GlobalQueryFilter
Este será o resultado
Agora vamos instalar as dependências do EntityFramework. Rode os seguintes comandos separadamente!
dotnet tool install --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
Substitua o código do arquivo Program.cs pelo snippet abaixo
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
namespace GlobalQueryFilter
{
class Program
{
static void Main(string[] args)
{
SetupDatabase();
using (var db = new Contexto())
{
var usuarios = db.Usuario.ToList();
Console.WriteLine("======== Usuários com Query filter aplicado ========");
foreach (var usuario in usuarios)
{
Console.WriteLine($"Nome: {usuario.Nome} Deletado: {usuario.IsDeleted}");
}
usuarios = db.Usuario.IgnoreQueryFilters().ToList();
Console.WriteLine("======== Usuários com Query filter ignorado ========");
foreach (var usuario in usuarios)
{
Console.WriteLine($"Nome: {usuario.Nome} Deletado: {usuario.IsDeleted}");
}
}
}
private static void SetupDatabase()
{
using (var db = new Contexto())
{
if (db.Database.EnsureCreated())
{
db.Usuario.Add(new Usuario { Nome = "Usuario 1", IsDeleted = false });
db.Usuario.Add(new Usuario { Nome = "Usuario 2", IsDeleted = true });
db.Usuario.Add(new Usuario { Nome = "Usuario 3", IsDeleted = false });
db.Usuario.Add(new Usuario { Nome = "Usuario 4", IsDeleted = true });
db.SaveChanges();
}
}
}
}
#region Entidade
public class Usuario
{
public int Id { get; set; }
public string Nome { get; set; }
public bool IsDeleted { get; set; }
}
#endregion
#region Contexto EntityFramework
public class Contexto : DbContext
{
public DbSet<Usuario> Usuario { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer(
@"Server=.;Database=Demo.QueryFilters;Trusted_Connection=True;ConnectRetryCount=0;");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Configurando o Global Query Filter
modelBuilder.Entity<Usuario>().HasQueryFilter(p => !p.IsDeleted);
}
}
#endregion
}
Excute o comando abaixo para executar a aplicação
dotnet run
Este é o resultado esperado após a execução da aplicação
Note que não foi necessário adicionar filtro para que fossem retornados usuarios não deletados
var usuarios = db.Usuario.ToList();
Ignorar o Global Query Filter é um processo extremamente simples, basta usar o método IgnoreQueryFilters
var usuarios = db.Usuario.IgnoreQueryFilters().ToList();
O código do projeto está disponiível no nosso GitHub
Commentaires