Skip to content

Instantly share code, notes, and snippets.

@shahabganji
Last active January 2, 2022 15:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shahabganji/adc370434873eb845ac2c122206c74ac to your computer and use it in GitHub Desktop.
Save shahabganji/adc370434873eb845ac2c122206c74ac to your computer and use it in GitHub Desktop.
Explore Global Query Filters in EF Core
public class Author
{
// omitted code
public Guid Id { get; private set; }
public string FirstName { get; private set; }
public string LastName { get; private set; }
public DateTime DateOfBirth { get; private set; }
public bool IsDeleted { get; private set; }
}
var authors = context.Authors
.Where(author => author.LastName.StartsWith("joh"));
public class BookstoreDbContext : DbContext
{
// omitted code
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Author>()
.HasQueryFilter(author => !author.IsDeleted);
base.OnModelCreating(modelBuilder);
}
public DbSet<Author> Authors { get; set; }
}
public interface ICanBeSoftDeleted
{
bool IsDeleted{ get; set;}
}
public class Author : ICanBeSoftDeleted
{
// omitted code
}
public class Book : ICanBeSoftDeleted
{
// omitted code
}
var authors = context.Authors
.Where(author => author.LastName.StartsWith("joh"))
.IgnoreQueryFilters();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var softDeleteEntities = typeof(ICanBeSoftDeleted).Assembly.GetTypes()
.Where(type => typeof(ICanBeSoftDeleted)
.IsAssignableFrom(type)
&& type.IsClass
&& !type.IsAbstract);
foreach (var softDeleteEntity in softDeleteEntities)
{
modelBuilder.Entity(softDeleteEntity)
.HasQueryFilter(
GenerateQueryFilterLambda(softDeleteEntity)
);
}
base.OnModelCreating(modelBuilder);
}
private LambdaExpression GenerateQueryFilterLambdaExpression(Type type)
{
// we should generate: e => e.IsDeleted == false
// or: e => !e.IsDeleted
// e =>
var parameter = Expression.Parameter(type, "e");
// false
var falseConstant = Expression.Constant(false);
// e.IsDeleted
var propertyAccess = Expression.PropertyOrField(parameter, nameof(ICanBeSoftDeleted.IsDeleted));
// e.IsDeleted == false
var equalExpression = Expression.Equal(propertyAccess, falseConstant);
// e => e.IsDeleted == false
var lambda = Expression.Lambda(equalExpression, parameter);
return lambda;
}
SELECT a.*
FROM dbo.Authors as a
WHERE a.LastName LIKE 'joh%'
AND a.IsDelete = 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment