Entity Framework – Usage of Global Query Filters
- Posted by Muthukumar Dharmar
- Categories EF Core, Entity Framework
- Date July 19, 2021
In this short article, we will look into a simple use case where we use a Global Query Filter feature in Entity Framework.
Scenario / Use Case
There might be cases, we need to apply default filter criteria, whenever we query a table.
For example, We have a requirement, not to hard delete the record instead we should maintain a column IsDeleted (or) IsActive to track the status. Here, in this case, we need to filter this column by default for all types of queries. It could be: Retrieve item by Id, Retrieve all items, Retrieve items by search criteria, etc.,
We can use Global Query Filter to solve such problems.
Usage
Applying the global query filter in OnModelCreating method of our DbContext class. Below is a Generic method that will apply Global filter for a given entity.
protected virtual void ApplyIsDeletedGlobalFilter<T>(ModelBuilder modelBuilder) where T : class, ISoftDeleteEntity { modelBuilder.Entity<T>().HasQueryFilter(e => !e.IsDeleted); }
Then we can invoke the method inside our OnModelCreating method as below. Hereafter in our whole project wherever we query any of these tables by default, it will add a where clause to exclude deleted records.
protected override void OnModelCreating(ModelBuilder modelBuilder) { this.ApplyIsDeletedGlobalFilter<TTenant>(modelBuilder); this.ApplyIsDeletedGlobalFilter<TTenantBranch>(modelBuilder); this.ApplyIsDeletedGlobalFilter<Product>(modelBuilder); this.ApplyIsDeletedGlobalFilter<ProductAllocation>(modelBuilder); this.ApplyIsDeletedGlobalFilter<ProductAccess>(modelBuilder); this.ApplyIsDeletedGlobalFilter<BusinessDomain>(modelBuilder); this.ApplyIsDeletedGlobalFilter<ProductType>(modelBuilder); this.ApplyIsDeletedGlobalFilter<Configuration>(modelBuilder); base.OnModelCreating(modelBuilder); }
Ignore Global Filter
Now, You might have a question, what If I need to query including all these deleted records. In other words, how can I ignore this global filter for a particular query? This can be done using IgnoreQueryFilters method from Entity Framework.
var pa = await _context.ProductAllocations.IgnoreQueryFilters() .FirstOrDefaultAsync(pa => pa.TenantId == paform.ProductAllocation.TenantId && pa.ProductId == paform.ProductAllocation.ProductId );
Hope you have enjoyed this article 🙂
Tag:EF, EF Core, EntityFramework, LINQ to SQL