Entity
Framework
Core - Aplicando Global Query Filters
![]() |
Neste artigo vou apresentar o recurso Global Query Filters do Entity Framework Core. |
![]() |
O recurso Global Query Filters do Entity Framework Core também é conhecido como filtro de consulta a nível de modelo, e, permite especificar um filtro a nível de modelo que é aplicado de forma automática a todas as consultas que são executadas no contexto do tipo especificado.
Dessa forma a estrutura de entidade adiciona automaticamente o filtro na cláusula where antes de executar as consultas LINQ. Normalmente, os filtros de consulta global são aplicados no método de contexto OnModelCreating. Esses filtros também são aplicados automaticamente às consultas LINQ envolvendo tipos de entidade que são indiretamente referenciados, como os incluídos como uma propriedade de navegação.
Geralmente esse recurso é aplicado em uma exclusão reversível onde temos um campo do tipo booleano como IsDeleted.
No
cenário da exclusão reversível você não exclui
os objetos do banco de dados, em vez disso, você os marca como não sendo mais
válidos, definindo as flags IsValid/IsCurrent ou Status para
0
(inativo) ou 1 (ativo) na sua aplicação.
Parece siimples mas você precisa lembrar que, ao obter objetos do banco de
dados, você deve fornecer apenas os dados válidos - os objetos inválidos
devem ser filtrados.
Verificar uma flag IsValid/IsCurrent/Status sempre quando o banco de dados fizer uma consulta pode levar a problemas porque você pode simplesmente esquecer de verificar o sinalizador utilizado.
Aqui
entra o Globl Query Filters e opção HasQueryFilter que iremos aplicar no
exemplo.
No exemplo deste artigo vou usar o banco de dados Cadastro.mdf e a tabela
Paises que tem a seguinte estrutura e dados:
![]() |
![]() |
Na tabela Paises temos o campo IsAtivo do tipo bit que pode ser true(1) ou false(0).
Vamos
aplicar o recurso Global Query Filters e
ver
como isso funciona na prática..
Recursos usados:
Criando a solução e o projeto no VS Community
Abra o VS 2017 Community e clique em Visual C# -> .NET Core e escolha o template Console App(.NET Core) :
Informe o nome EFCore_GlobalQueryFilter e clique em OK;
Agora vamos incluir as seguintes referências via Nuget em nosso projeto:
Microsoft.EntityFrameworkCore.SqlServer
No menu Tools clique em Nuget Package Manager e a seguir em Manage Nuget Packages for Solution;
Clique em Browse e localize o pacote e a seguir marque o projeto e clique em Install.
Repita o procedimento acima para cada pacote.
Criando o modelo de entidades
Crie uma pasta chamada Models no projeto e a seguir crie a classe Pais conforme o código mostrado a seguir:
1- Pais
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace EFCore_GlobalQueryFilter.Models
{
[Table("Paises")]
public class Pais
{
[Key]
public int Id { get; set; }
public string Nome { get; set; }
public string Codigo { get; set; }
public bool IsAtivo { get; set; }
}
}
|
Na pasta Models crie a classe de contexto chamada PaisDbContext que herda de DbContext e onde vamos definir o mapeamento:
5- PaisDbContext
using Microsoft.EntityFrameworkCore;
namespace EFCore_GlobalQueryFilter.Models
{
public class PaisDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Data Source=Macoratti;Initial Catalog=Cadastro;Integrated Security=True");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//-------------------------------------------------
//aplicando o Global Query Filter ao campo IsAtivo
//-------------------------------------------------
modelBuilder.Entity<Pais>()
.HasQueryFilter(p => !p.IsAtivo);
base.OnModelCreating(modelBuilder);
}
public DbSet<Pais> Paises { get; set; }
}
}
|
Nesta classe PaisDbContext definimos a propriedade Paises do tipo DbSet que vai mapear a entidade Pais para a tabela Paises.
No método OnModelCreating estamos aplicando o filtro global usando HasQueryFilter :
modelBuilder.Entity<Pais>()
.HasQueryFilter(p => p.IsAtivo);
Aqui usamos a opção HasQueryFilter especificando um filtro que sempre será aplicado a todas as entidades do tipo. Primeiro você especifica o filtro da entidade e ele é aplicado automaticamente em todas as consultas quando você busca dados do banco de dados usando DbContext.
No exemplo vamos exibir somente as informações quando p.IsAtivo for igual a True ou 1.
Agora vamos testar o filtro aplicado
Definindo o código do método Main da classe Program
Vamos agora definir o código no método Main() da classe Program conforme abaixo:
using EFCore_GlobalQueryFilter.Models;
using System.Linq;
using static System.Console;
namespace EFCore_GlobalQueryFilter
{
class Program
{
static void Main(string[] args)
{
using (PaisDbContext context = new PaisDbContext())
{
WriteLine("---------------Usando Global Query Filters---------------");
var paisesAtivos = context.Paises.ToList();
foreach (var pais in paisesAtivos)
{
WriteLine($"{pais.Id}\t{pais.Nome}");
}
ReadLine();
}
}
}
}
|
Executando o projeto iremos obter o seguinte resultado:
No resultado acima vemos exibidos apenas os paises com campo IsAtivo igual a True ou valor 1.
Podemos também desabilitar o filtro global para uma consulta LINQ individual usando o método IgnoreQueryFilter().
Veja o exemplo abaixo:
using EFCore_GlobalQueryFilter.Models;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using static System.Console;
namespace EFCore_GlobalQueryFilter
{
class Program
{
static void Main(string[] args)
{
using (PaisDbContext context = new PaisDbContext())
{
WriteLine("---------------Usando Global Query Filters---------------");
var paises = context.Paises.ToList();
foreach (var pais in paises)
{
WriteLine($"{pais.Id}\t{pais.Nome}");
}
WriteLine("---------------Desabilitando Global Query Filters---------------");
var todosPaises = context.Paises.IgnoreQueryFilters().ToList();
foreach (var pais in todosPaises)
{
WriteLine($"{pais.Id}\t{pais.Nome}");
}
ReadLine();
}
}
}
}
|
No código acima estamos desabilitando o filtro global usando o método IgnoreQueryFilters().
Veja o resultado:
Este
recurso possui as seguintes limitações:
- Não pode conter referências a propriedades de navegação
- Pode ser definido apenas no tipo de Entidade raiz de uma hierarquia de herança
- O método IgnoreQueryFilters ignora todos os filtros no tipo de
entidade; ou seja, não podemos remover filtros particulares usando este método.
Pegue o
projeto completo aqui :
EFCore_GlobalQueryFilter.zip
"Naquele tempo, respondendo Jesus,
disse: Graças te dou, ó Pai, Senhor do céu e da terra, que ocultaste estas
coisas aos sábios e entendidos, e as revelaste aos pequeninos."
Mateus 11:25
Gostou ?
Compartilhe no Facebook
Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
EF Core - Iniciando com o Entity Framework Core - Macoratti.net
EF Core - Usando a abordagem DataBase First ... - Macoratti.net
ASP .NET Core e EF Core - Configurando o ambiente - Macoratti.net
EF Core - Apresentando o EF Core Power Tools - Macoratti.net
EF Core - Usando um Banco de dados In-Memory para ... - Macoratti.net
EF Core 2.0 - Scaffolding DbContext e Models usando CLI - Macoratti
ASP .NET Core - CRUD usando Blazor e Entity Framework ... - Macoratti
Curso Entity Framework Core 2.0 - Vídeo Aulas - Macoratti