1

I'm trying to build a search predicate dynamically but I'm having a little issue with nullable enums in my class.

This is my class and enum structure:

public class TestNullableEnumClass
{
    public TestingEnum? TestEn { get; set; }
}

public enum TestingEnum
{
    [Description("Item 1")]
    Item1,
    [Description("Item 2")]
    Item2,
    [Description("Item 3")]
    Item3,
    [Description("Item 4")]
    Item4,
    [Description("Item 5")]
    Item5
}

I now create a list of my classes with one class with an empty enum value:

List<TestNullableEnumClass> myList = new List<TestNullableEnumClass>();

myList.Add(new TestNullableEnumClass { TestEn = TestingEnum.Item1 });
myList.Add(new TestNullableEnumClass {  });

IQueryable<TestNullableEnumClass> query = myList.AsQueryable();

I now want to create an expression dynamically to filter the list where the TestNullableEnumClass has the property TestEn set to TestingEnum.Item1.

var predicate = PredicateBuilder.New<TestNullableEnumClass>();

var parameter = Expression.Parameter(typeof(TestNullableEnumClass), typeof(TestNullableEnumClass).Name);
Expression member = Expression.Property(parameter, type.Name);
var constant = Expression.Constant(TestingEnum.Item1);
var body = Expression.Equal(member, constant);
var expression = Expression.Lambda<Func<TestNullableEnumClass, bool>>(body, parameter);

predicate.Or(expression);

The above code fails on the Expression.Equal line with the following error:

{"The binary operator Equal is not defined for the types 'System.Nullable`1[ExpressionTest.TestingEnum]' and 'ExpressionTest.TestingEnum'."}

If I make the property TestEn a request field my code then works fine.

What do I need to add to get this to work with nullable enums?

I'm effectively trying to write the following dynamically:

var list = query.Where(x => x.TestEn.Equals(TestingEnum.Item1)).ToList();
Sun
  • 4,458
  • 14
  • 66
  • 108
  • Just wrap the `ExpressionTest.TestingEnum` in a `System.Nullable[ExpressionTest.TestingEnum]` so that both sides of the comparison are `System.Nullable[ExpressionTest.TestingEnum]` – sdgfsdh Jan 22 '18 at 16:34
  • ExpressionTest.TestingEnum is the namespace and enum definition! How can that be wrapped as a Nullable type? – Sun Jan 22 '18 at 16:58
  • `TestingEnum?` is syntax sugar for `System.Nullable`. – zneak Jan 22 '18 at 17:07
  • I believe that you just need to write `Expression.Constant((TestingEnum?)TestingEnum.Item1)` – zneak Jan 22 '18 at 17:12
  • No, that still causes the same error – Sun Jan 22 '18 at 17:19

1 Answers1

3

You need to convert your constant to the type of your member variable.

var predicate = PredicateBuilder.New<TestNullableEnumClass>();

var parameter = Expression.Parameter(typeof(TestNullableEnumClass), typeof(TestNullableEnumClass).Name);
Expression member = Expression.Property(parameter, type.Name);
var constant = Expression.Constant(TestingEnum.Item1);
var constantConverted = Expression.Convert(constant, member.Type);
var body = Expression.Equal(member, constantConverted);
var expression = Expression.Lambda<Func<TestNullableEnumClass, bool>>(body, parameter);

predicate.Or(expression);
diogenesgg
  • 2,601
  • 2
  • 20
  • 29