为可空枚举动态构建谓词

Dynamically build a predicate for a nullable enum

我正在尝试动态构建搜索谓词,但我在 class.

中遇到了可为空枚举的小问题

这是我的 class 和枚举结构:

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
}

我现在创建一个 classes 列表,其中一个 class 的枚举值为空:

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

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

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

我现在想动态创建一个表达式来过滤列表,其中 TestNullableEnumClass 将 属性 TestEn 设置为 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);

以上代码在 Expression.Equal 行失败并出现以下错误:

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

如果我将 属性 TestEn 作为请求字段,我的代码就可以正常工作。

我需要添加什么才能使其与可为 null 的枚举一起使用?

我正在有效地尝试动态编写以下内容:

var list = query.Where(x => x.TestEn.Equals(TestingEnum.Item1)).ToList();

您需要将常量转换为成员变量的类型。

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);