繁体   English   中英

将 Expression<> 应用于 LINQ Where 子句

[英]Applying an Expression<> to a LINQ Where clause

我正在编写一个自定义实体框架过滤器。 我有一个 ID 列表和一个用户提供的表达式。

protected IEnumerable<TColumn> FilterIds;
protected Expression<Func<T, IEnumerable<TColumn>, bool>> Filter;

现在我的问题是如何将Filter表达式应用于Where()子句?

public virtual IQueryable<T> ApplyFilter(IQueryable<T> query)
{
    if (FilterMode == FilterModeMatchAny && HasFilterIds)
    {
        // Whoops! Can't do this!
        return query.Where(x => Filter(x, FilterIds));
    }
    return query;

使用这篇文章中的Combine方法几乎可以满足您的所有需求。 从那里你只需要将文字值转换为计算它的表达式(或者我想改变该答案的Combine方法,以便中间值不是从 lambda 计算出来的,而是任何表达式),然后调用function。

protected IEnumerable<TColumn> FilterIds;
protected Expression<Func<T, IEnumerable<TColumn>> FilterIdsExpression => _ => FilterIds;
protected Expression<Func<T, IEnumerable<TColumn>, bool>> Filter;

public virtual IQueryable<T> ApplyFilter(IQueryable<T> query)
{
    if (FilterMode == FilterModeMatchAny && HasFilterIds)
    {
        return query.Where(FilterIdsExpression.Combine(Filter));
    }
    return query;
}

您可以创建一个新表达式以使用FilterIds调用Filter并使用来自LinqKitExpand

编辑感谢@Servy 的评论。 现在我只扩展内部表达式而不是整个查询。

...
protected IEnumerable<TColumn> FilterIds;
protected Expression<Func<T, IEnumerable<TColumn>, bool>> Filter;

public virtual IQueryable<T> ApplyFilter(IQueryable<T> query)
{
    if (FilterMode == FilterModeMatchAny && HasFilterIds)
    {
        Expression<Func<T, bool>> expression = x => Filter.Invoke(x, FilterIds);
        return query.Where(expression.Expand());
    }
    return query;
}
...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM