Sam*_*Sam 0 c# ienumerable iqueryable func expression-trees
捎带一个非常相似的问题 ......
我需要从ViewModel生成一个表达式作为搜索谓词传递.我需要能够根据用户提供的内容包含/排除查询参数.例:IQueryable.Where
public class StoresFilter
{
public int[] Ids { get; set; }
[StringLength(150)]
public string Name { get; set; }
[StringLength(5)]
public string Abbreviation { get; set; }
[Display(Name = "Show all")]
public bool ShowAll { get; set; } = true;
public Expression<Func<Store, bool>> ToExpression()
{
List<Expression<Func<Store, bool>>> expressions = new List<Expression<Func<Store, bool>>>();
if (Ids != null && Ids.Length > 0)
{
expressions.Add(x => Ids.Contains(x.Id));
}
if (Name.HasValue())
{
expressions.Add(x => x.Name.Contains(Name));
}
if (Abbreviation.HasValue())
{
expressions.Add(x => x.Abbreviation.Contains(Abbreviation));
}
if (!ShowAll)
{
expressions.Add(x => x.Enabled == true);
}
if (expressions.Count == 0)
{
return x => true;
}
// how to combine list of expressions into composite expression???
return compositeExpression;
}
}
Run Code Online (Sandbox Code Playgroud)
有一种简单的方法可以从表达式列表中构建复合表达式吗?或者我需要经历的过程中采用人工制作的表情ParameterExpression,Expression.AndAlso, ExpressionVisitor,等?
你不应该构建和组合Expressions,但是你应该通过IQuerable<Store>via .Wherechain 来实现它.而且,source.Expression将包含所需的表达式:
public IQueryable<Store> ApplyFilter(IQueryable<Store> source)
{
if (Ids != null && Ids.Length > 0)
source = source.Where(x => Ids.Contains(x.Id));
if (Name.HasValue())
source = source.Where(x => x.Name.Contains(Name));
if (Abbreviation.HasValue())
source = source.Where(x => x.Abbreviation.Contains(Abbreviation));
if (!ShowAll)
source = source.Where(x => x.Enabled == true);
//or return source.Expression as you wanted
return source;
}
Run Code Online (Sandbox Code Playgroud)
用法:
var filter = new StoresFilter { Name = "Market" };
var filteredStores = filter.ApplyFilter(context.Stores).ToList();
Run Code Online (Sandbox Code Playgroud)