-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automatically perform required conversions when query filter is defined on interface or base type #10257
Comments
@nphmuller This is something that can be done with bulk configuration on the mapped entity types: protected override void OnModelCreating(ModelBuilder modelBuilder)
{
foreach (var entityType in modelBuilder.Model.GetEntityTypes()
.Where(e => typeof(ISoftDeletableEntity).IsAssignableFrom(e.ClrType)))
{
modelBuilder
.Entity(entityType.ClrType)
.HasQueryFilter(ConvertFilterExpression<ISoftDeletableEntity>(e => !e.IsDeleted, entityType.ClrType));
}
}
private static LambdaExpression ConvertFilterExpression<TInterface>(
Expression<Func<TInterface, bool>> filterExpression,
Type entityType)
{
var newParam = Expression.Parameter(entityType);
var newBody = ReplacingExpressionVisitor.Replace(filterExpression.Parameters.Single(), newParam, filterExpression.Body);
return Expression.Lambda(newBody, newParam);
} Making a better experience around this is covered by #9117 and #6787. The code is more complicated in this case than in many others because it requires constructing a lambda expression where the parameter is validated to be the exact entity type--not the interface. I'm going to re-purpose this bug to automatically handle base types/interfaces in EF code. After this issue is fixed it should be possible to simplify the above to: protected override void OnModelCreating(ModelBuilder modelBuilder)
{
Expression<Func<ISoftDeletableEntity, bool>> expression = e => !e.IsDeleted;
foreach (var entityType in modelBuilder.Model.GetEntityTypes()
.Where(e => typeof(ISoftDeletableEntity).IsAssignableFrom(e.ClrType)))
{
modelBuilder.Entity(entityType.ClrType).HasQueryFilter(expression);
}
} |
@ajcvickers Wouldn't be more efficient to set |
@ajcvickers Totally agree with the repurpose. The sample after the fix is way easier to write. |
I've set up a Gist which shows my query filter use-case and the code I had to write to get it working. |
Note from triage: if we implement this, then it will be as part of general mapping configuration for all uses of an interface, tracked by #6787. |
Say I have the following interface that can be implemented on any entity that I want to support soft-deletion.
It would be nice to be able to define a global query filter for any entity type that implements this interface like this:
Currently this throws the following exception:
System.ArgumentException: 'The entity type 'MyApp.ISoftDeletableEntity' provided for the argument 'clrType' must be a reference type.'
The text was updated successfully, but these errors were encountered: