为可空枚举动态构建谓词
Posted
技术标签:
【中文标题】为可空枚举动态构建谓词【英文标题】:Dynamically build a predicate for a nullable enum 【发布时间】:2018-01-22 16:29:55 【问题描述】:我正在尝试动态构建搜索谓词,但我的班级中的可空枚举存在一些问题。
这是我的类和枚举结构:
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 行上失败,并出现以下错误:
"二元运算符 Equal 没有为类型 'System.Nullable`1[ExpressionTest.TestingEnum]' 和 'ExpressionTest.TestingEnum' 定义。"
如果我将属性 TestEn 设置为请求字段,我的代码就可以正常工作。
我需要添加什么才能使其与可空枚举一起使用?
我正在有效地尝试动态编写以下内容:
var list = query.Where(x => x.TestEn.Equals(TestingEnum.Item1)).ToList();
【问题讨论】:
只需将ExpressionTest.TestingEnum
包裹在System.Nullable[ExpressionTest.TestingEnum]
中,这样比较的两边都是System.Nullable[ExpressionTest.TestingEnum]
ExpressionTest.TestingEnum 是命名空间和枚举定义!如何将其包装为 Nullable 类型?
TestingEnum?
是System.Nullable<TestingEnum>
的语法糖。
相信你只需要写Expression.Constant((TestingEnum?)TestingEnum.Item1)
不,仍然会导致同样的错误
【参考方案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);
【讨论】:
那是完美的。谢谢。以上是关于为可空枚举动态构建谓词的主要内容,如果未能解决你的问题,请参考以下文章