我正在创建一个迄今为止效果很好的通用Where过滤器(仅对Contains
过滤器感兴趣):
private static MethodInfo contains = typeof(string).GetMethod("Contains");
private static Expression<Func<T, bool>> GetFilter<T>(string propertyName, string value)
{
var item = Expression.Parameter(typeof(T), "item");
var member = Expression.Property(item, propertyName);
var constant = Expression.Constant(value);
var body = Expression.Call(member, contains, constant);
return Expression.Lambda<Func<T, bool>>(body, item);
}
有什么方法可以扩展这个,以便我可以通过导航属性进行搜索?我使用Expression
非常新,所以我不确定要尝试什么。
一个例子是:
public class A
{
public int BId { get; set; }
public B B { get; set; }
}
public class B
{
public string Name { get; set; }
}
dbContext.As
.Where(GetFilter<A>("B.Name", "Hello World"))
.ToList();
但是Expression.Property("B.Name")
上的内容失败了:
未为类型
定义实例属性B.Name
A
答案 0 :(得分:4)
您需要为属性路径中的每个属性按顺序创建每个成员访问权限:
private static Expression<Func<T, bool>> GetFilter<T>(string propertyName, string value)
{
var item = Expression.Parameter(typeof(T), "item");
Expression member = item;
foreach (var prop in propertyName.Split('.'))
{
member = Expression.Property(member, prop);
}
var constant = Expression.Constant(value);
var body = Expression.Call(member, contains, constant);
return Expression.Lambda<Func<T, bool>>(body, item);
}