System.Enum MethodCallExpression (HasFlag) mapped to TDestinationEnum MethodCallExpression
engenb opened this issue · 3 comments
Microsoft.AspNetCore.OData 8.2.5
AutoMapper.AspNetCore.OData.EFCore 5.0.0
AutoMapper.Extensions.ExpressionMapping 7.0.0
Microsoft.EntityFrameworkCore.SqlServer 8.0.4
I'll summarize here, but the original issue can be found on StackOverflow.
I've also set up a repository demonstrating the issue on GitHub.
I need an OData query endpoint that supports the enum has
operator such as $filter=type has 'SomeEnumValue'
. The ODataQueryOptions<TModel>.ToFilterExpression()
extension in AutoMapper.AspNetCore.OData.EFCore is producing an InstanceMethodCallExpression
where the (MethodInfo) Method
is (System.Enum).HasFlag(TModelEnum)
. This seems on track in, in my opinion.
If I map this expression, the resulting mapped InstanceMethodCallExpression
has (MethodInfo) Method
(TDestinationEnum).HasFlag(TDestinationEnum)
. I've confirmed this is causing a problem for me downstream when this filter is used later with EFCore. The stack trace can be found in the SO post mentioned above - I won't muck up this issue with a probably unnecessary stack trace. I think this is a result of XpressionMapperVisitor.VisitMethodCall
, maybe GetInstanceExpression
, found here.
This causes a problem when used with EFCore as the Linq -> SQL conversion doesn't accept the (TDestinationEnum).HasFlag(...)
method. It seems to only accept the (System.Enum).HasFlag(...)
flavor of this method.
FWIW, I think I can work around this by using my own replacement IQueryable
extensions in place of AutoMapper.AspNetCore.OData.EFCore with my own ExpressionVisitor
to adjust the mapped InstanceMethodCallExpression
back to the (System.Enum).HasFlag(...)
one after it has been mapped with this framework.
Would you agree that this may be a "special" enum case that could/should be accounted for in ExpressionMapping, to change the parameter type, but not change the method's declaring/reflected type?
Or, since this is EFCore-specific, is this something AutoMapper.AspNetCore.OData.EFCore needs to handle after the expression has been mapped to ensure the resulting filter is efcore-compatible?
Curious to hear thoughts from the authors of this framework. I'd be happy to help with a PR as well, but I can't do that immediately because my immediate priority is getting a workaround in place. I should be able to circle back to this later in the week though.
I think you're correct. If the initial type System.Enum
is not in the configuration it should not be updated. It looks like the MethodInfo
for the mapped expression should be created from the declaring type.
@engenb - can you confirm the myget build works?