C# Create a LambdaExpression that compares two member properties (for EF Core HasQueryFilter)

.net .net-core c# entity-framework entity-framework-core


I try to apply a query filter in the OnModelCreating method (Entity Framework Core) for all entities which have a ClientId property (int). So far I am able to filter the entities but I struggle to invoke the HasQueryFilter for those entities.

The filter should compare the ClientId property of the current Entity with a property from a service called ITenantProvider.

This is how I do it manually:

modelBuilder.Entity<MyEntity>().HasQueryFilter(a => a.ClientId == _tenantProvider.TenantId);

Unfortunately, the EF Core HasQueryFilter method without Generic takes a LambdaExpression:

public virtual EntityTypeBuilder HasQueryFilter([CanBeNullAttribute] LambdaExpression filter);

I don't know how I can translate the above call to a Lambda Expression. My current code looks like this:

foreach (var entityType in modelBuilder.Model.GetEntityTypes().Where(e =>
    e.GetProperties().Select(property => property.Name).Any(pName => pName.Equals("ClientId"))))
    var clientId = entityType.FindProperty("ClientId");
    if (clientId != null && clientId.ClrType == typeof(int))
        var parameter = Expression.Parameter(entityType.ClrType, "p");
        var filter = Expression.Lambda(Expression.Equal(Expression.Property(parameter, clientId.PropertyInfo), Expression.Constant(_tenantProvider.TenantId), parameter);
        entityType.QueryFilter = filter;

Which basically works for the first call but since I use Expression.Constant it doesn't work for the next request if the _tenantProvider.TenantId changes.

How can I compare the Entity ClientId property with _tenantProvider.TenantId at runtime?

12/14/2018 9:52:03 AM

Accepted Answer

The easiest way to get the runtime expression equivalent of the


is to build a compile time parameterless lambda expression and get its Body:

var parameter = Expression.Parameter(entityType.ClrType, "p");
var left = Expression.Property(parameter, clientId.PropertyInfo);
Expression<Func<int>> tenantId = () => _tenantProvider.TenantId;
var right = tenantId.Body;
var filter = Expression.Lambda(Expression.Equal(left, right), parameter);
12/14/2018 12:16:20 PM

Popular Answer

Suppose the instance of TenantProvider does not change:

Then instead of the constant expression you could use


If you reinstantiate it at some point this will not work anymore.

Suppose you have some static property that provides the tennant id, then you could use:


Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow