我想编写过滤控件,它采用对象类型T
和属性名称,并返回Expression<Func<T, bool>>
来检查传递属性的值。我不想使用反射,因为我担心EF不能使用这些表达式。我不能使用委托,因为C#没有属性的委托。我能做什么?也许我应该使用不同的方法来编写这些控件?
这是我使用反射的第一种方法:
public string FilteringField { get; set; }
public Expression<Func<T, bool>> GetFilterExpression()
{
if (cmbValue.SelectedIndex == 1)
return (o => (bool)typeof(T).GetProperty(FilteringField).GetValue(o, null));
if (cmbValue.SelectedIndex == 2)
return (o => !(bool)typeof(T).GetProperty(FilteringField).GetValue(o, null));
return null;
}
答案 0 :(得分:3)
这里的反思不是问题; EF甚至无法注意到差异。顺便说一句,委托方法是非首发的(因为你提到EF);最终,它是这样的:
public static IQueryable<T> Where<T>(this IQueryable<T> query,
string propertyName, object value)
{
PropertyInfo prop = typeof(T).GetProperty(propertyName);
var param = Expression.Parameter(typeof(T), "x");
var body = Expression.Equal(
Expression.Property(param, prop),
Expression.Constant(value, prop.PropertyType)
);
var predicate = Expression.Lambda<Func<T, bool>>(body, param);
return query.Where(predicate);
}
请注意,Expression.PropertyOrField(propertyName)
可以让您更轻松;我之前没有使用它的原因是在创建常量时知道成员类型(prop.PropertyType
)非常方便 - 否则你可能会遇到空值问题。
答案 1 :(得分:0)
我知道这是一个陈旧的答案,但如果有人看到这个我已经建立了这个项目:
https://github.com/PoweredSoft/DynamicLinq
也可以在nuget上下载:
https://www.nuget.org/packages/PoweredSoft.DynamicLinq
你可以简单地做
query.Where("FirstName", ConditionOperators.Equal, "David");