We use System.Linq.Expressions.Expression
to create custom expressions that apply to .Where()
ours IQueryable
.
What I want to achieve is to apply the method .HasFlag()
( introduced in EF 6.1 ) for the property that is then used in the expression .Where()
.
I have the following code:
var memberExpression = propertyExpression as MemberExpression;
var targetType = memberExpression?.Type ?? typeof(decimal?);
var value = Enum.Parse(type, searchValue);
var hasFlagMethod = targetType.GetMethod(nameof(Enum.HasFlag));
var hasFlagExpression = Expression.Call(propertyExpression, hasFlagMethod, Expression.Convert(Expression.Constant(value), typeof(Enum)));
The value is propertyExpression
displayed as {x.Type}
, and hasFlagMethod
displayed as {Boolean HasFlag(System.Enum)}
, which both look great.
The value hasFlagExpression
is equal {x.Type.HasFlag(Convert(Foo))}
, which also looks completely normal for me, except for the part Convert(Foo)
, but it needed something else, because I would get another exception that complains that this parameter cannot be applied to this method because it is not System.Enum
.
And while we are listing IQueryable
using this .Where()
, we get the following exception:
NotSupportedException: LINQ to Entities does not recognize the method
'Boolean HasFlag(System.Enum)' method, and this method cannot
be translated into a store expression.
Calling it directly on IQueryable
does work, though (we also use EF 6.1, which added support for Enum.HasFlag()
), as in
Entities.Where(x => x.Type.HasFlag(BarEnum.Foo));
But a call of this type is not an option, since it should be common to all our objects. (We put these conditions .Where()
together according to the filtered columns in our datatables)