动态构建可为空的枚举的谓词

时间:2018-01-22 16:29:56

标签: c# lambda predicate predicatebuilder

我正在尝试动态构建一个搜索谓词,但是我的班级中有一个可以为空的枚举的问题。

这是我的类和枚举结构:

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
}

我现在用一个具有空枚举值的类创建我的类列表:

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行上失败,并出现以下错误:

{“没有为类型'System.Nullable`1 [ExpressionTest.TestingEnum]'和'ExpressionTest.TestingEnum'定义二元运算符Equal。”}

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

我需要添加什么才能让它与可以为空的枚举一起使用?

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

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

1 个答案:

答案 0 :(得分:1)

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

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