如何传递另一类型的Linq语句

本文关键字:Linq 语句 类型 何传递 | 更新日期: 2023-09-27 18:12:54

下面我有一个方法包装另一个方法。我想做的是提供一个可选参数来过滤内部方法,它与t的类型不同。

这是被认为是"公共"API的外部方法:

public override IQueryable<T> GetEverything()
{
    return Get()
        .Where(i => i.Active == true)
        .Select(i => new T(i));
}

作为伪代码,我想这样做:

var items = GetEverything(x => x.SomeValue > 10);

会像这样传递到方法中

   public override IQueryable<T> GetEverything(???)
    {
        return Get()
            .Where(i => i.Active == true)
            .Where(x => x.SomeValue > 10)
            .Select(i => new T(i));
    }

注意,我仍然想保留我的i.Active过滤器,并且不想在开发人员决定传入过滤器时丢失它。传入的过滤器将复合不替换内部过滤器。有人能帮忙吗?任何帮助或建议将非常感激!

如何传递另一类型的Linq语句

Queryable.Where的签名:

public static IQueryable<TSource> Where<TSource>(
    this IQueryable<TSource> source,
    Expression<Func<TSource, bool>> predicate
)

因此,为了将参数传递给Where,最简单的方法是要求Expression<Func<TSource, bool>>:

public override IQueryable<T> GetEverything(Expression<Func<T, bool>> predicate)
{
    return Get()
        .Where(i => i.Active == true)
        .Where(predicate)
        .Select(i => new T(i));
}

请注意,大多数查询提供程序对哪些表达式可以转换为底层存储查询有限制,因此,如果为过滤器提供了一个开放的大门,可能会遇到更多的运行时错误。

如果你想保持一个单一的方法,并允许一个null谓词,你可以直接链接Linq表达式:

public override IQueryable<T> GetEverything(Expression<Func<T, bool>> predicate = null)
{
    var query = Get().Where(i => i.Active == true);
    if(predicate != null)
        query = query.Where(predicate);
    return query.Select(i => new T(i));
}