Skip to content

Syntax IN dont work with nullable Enums #931

@fheck

Description

@fheck

Similar to #63, I try to build an expression where I want to filter with enum string-values in a list.
Edit: Tested with versions 1.6.4 and 1.6.5.

Consider the following model:

public class Test
{
    public TestEnum? EnumValue { get; set; }
}

public enum TestEnum
{
    Undefined = 0,
    Value1 = 1,
    Value2 = 2,
    Other = 3,
}

Now I try to use the following expression:
"it.EnumValue in (\"Value1\",\"Value2\")"

Unfortunately, this results in the following exception:

System.InvalidOperationException: No coercion operator is defined between types 'System.Nullable`1[TestEnum]' and 'System.Nullable`1[System.Decimal]'.
   at System.Linq.Expressions.Expression.GetUserDefinedCoercionOrThrow(ExpressionType coercionType, Expression expression, Type convertToType)
   at System.Linq.Dynamic.Core.Parser.ExpressionPromoter.Promote(Expression sourceExpression, Type type, Boolean exact, Boolean convertExpression)
   at System.Linq.Dynamic.Core.Parser.SupportedMethods.MethodFinder.IsApplicable(MethodData method, Expression[] args)
   at System.Linq.Dynamic.Core.Parser.SupportedMethods.MethodFinder.<>c__DisplayClass10_0.<FindBestMethodBasedOnArguments>b__1(MethodData m)
   at System.Linq.Enumerable.WhereEnumerableIterator`1.ToArray()
   at System.Linq.Dynamic.Core.Parser.SupportedMethods.MethodFinder.FindBestMethodBasedOnArguments(IEnumerable`1 methods, Expression[]& args, MethodBase& method)
   at System.Linq.Dynamic.Core.Parser.SupportedMethods.MethodFinder.FindMethod(Type type, String methodName, Boolean staticAccess, Expression& instance, Expression[]& args, MethodBase& method)
   at System.Linq.Dynamic.Core.Parser.SupportedMethods.MethodFinder.ContainsMethod(Type type, String methodName, Boolean staticAccess, Expression instance, Expression[]& args)
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.CheckAndPromoteOperands(Type signatures, TokenId opId, String opName, Expression& left, Expression& right, Int32 errorPos)
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseIn()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAndOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseOrOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLambdaOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseNullCoalescingOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseConditionalOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.Parse(Type resultType, Boolean createParameterCtor)
   at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(Type delegateType, ParsingConfig parsingConfig, Boolean createParameterCtor, ParameterExpression[] parameters, Type resultType, String expression, Object[] values)
   at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(ParsingConfig parsingConfig, Boolean createParameterCtor, ParameterExpression[] parameters, Type resultType, String expression, Object[] values)
   at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(ParsingConfig parsingConfig, Boolean createParameterCtor, Type itType, Type resultType, String expression, Object[] values)
   at System.Linq.Dynamic.Core.DynamicQueryableExtensions.Where(IQueryable source, ParsingConfig config, String predicate, Object[] args)
   at System.Linq.Dynamic.Core.DynamicQueryableExtensions.Where[TSource](IQueryable`1 source, ParsingConfig config, String predicate, Object[] args)

If I change the expression and try to go with an parameter instead:

"it.EnumValue in @0", new Dictionary<string, object>{ ["@0", new List<TestEnum> { TestEnum.Value1, TestEnum.Value2 }

I get the following, different, exception:

System.InvalidOperationException: No generic method 'Contains' on type 'System.Linq.Enumerable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic. 
   at System.Linq.Expressions.Expression.FindMethod(Type type, String methodName, Type[] typeArgs, Expression[] args, BindingFlags flags)
   at System.Linq.Expressions.Expression.Call(Type type, String methodName, Type[] typeArguments, Expression[] arguments)
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseIn()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseAndOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseOrOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseLambdaOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseNullCoalescingOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.ParseConditionalOperator()
   at System.Linq.Dynamic.Core.Parser.ExpressionParser.Parse(Type resultType, Boolean createParameterCtor)
   at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(Type delegateType, ParsingConfig parsingConfig, Boolean createParameterCtor, ParameterExpression[] parameters, Type resultType, String expression, Object[] values)
   at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(ParsingConfig parsingConfig, Boolean createParameterCtor, ParameterExpression[] parameters, Type resultType, String expression, Object[] values)
   at System.Linq.Dynamic.Core.DynamicExpressionParser.ParseLambda(ParsingConfig parsingConfig, Boolean createParameterCtor, Type itType, Type resultType, String expression, Object[] values)
   at System.Linq.Dynamic.Core.DynamicQueryableExtensions.Where(IQueryable source, ParsingConfig config, String predicate, Object[] args)
   at System.Linq.Dynamic.Core.DynamicQueryableExtensions.Where[TSource](IQueryable`1 source, ParsingConfig config, String predicate, Object[] args)

It seems the nullabilty of the property breaks something in the expression parser. But I'm not sure how to work around this at the moment.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions