LINQ to Entities does not recognize the "Boolean HasFlag (System.Enum)" method when creating an expression through System.Linq.Expressions.Expression

We use System.Linq.Expressions.Expressionto 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 propertyExpressiondisplayed as {x.Type}, and hasFlagMethoddisplayed as {Boolean HasFlag(System.Enum)}, which both look great.

The value hasFlagExpressionis 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 IQueryableusing 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 IQueryabledoes 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)

+4
1

MethodInfo HasFlag , - . ReflectedType typeof(YourEnum), - typeof(Enum). DeclaringType - typeof(Enum), , , , EF .

,

var hasFlagMethod = targetType.GetMethod(nameof(Enum.HasFlag));

var hasFlagMethod = typeof(Enum).GetMethod(nameof(Enum.HasFlag));
+3

Source: https://habr.com/ru/post/1686483/


All Articles