如何在 LINQ where 子句中传递 func 表达式?

Oka*_*min 5 c# linq iqueryable where-clause entity-framework-core

这是我要传入 where 子句的自定义过滤器(Func)

Func<Project,bool> filter = f =>
{
    bool filteredContent = true;
    if (!CreatorId.Equals(0))
        filteredContent = f.CreatedBy.Equals(CreatorId);

    if (filteredContent && !VerticalMarketId.Equals(0))
        filteredContent = f.VerticalMarketsId.Equals(VerticalMarketId);

    if (filteredContent && !ProductCategoryId.Equals(0))
        filteredContent = f.ProductCategoriesId.Equals(ProductCategoryId);

    return filteredContent;

};
Run Code Online (Sandbox Code Playgroud)

这是我的代码,我根据过滤器表达式中创建的条件获取所有项目

 getProjects = await _context.Projects.Where(x => x.IsDeleted == false && filter.Invoke(x))// Here I'm getting the exception
                .Include(PC => PC.ProjectComments.Where(x => x.IsDeleted == false))
                .Include(SP => SP.SharedProjects)
                .AsNoTracking().ToListAsync();
Run Code Online (Sandbox Code Playgroud)

异常:无法翻译 LINQ 表达式(DbSet......)。以可翻译的形式重写查询,或者通过插入对“AsEnumerable”、“AsAsyncEnumerable”、“ToList”或“ToListAsync”的调用来显式切换到客户端计算。

有人可以告诉我如何使用其中的表达式过滤数据吗?

注意:我可以在应用过滤器之前执行 ToListAsync() ,但它会从数据库获取所有记录,然后在客户端进行过滤。但我想在服务器端过滤数据。

Oka*_*min 4

我通过创建一个简单的表达式来解决这个问题,如下所示:

private static Expression<Func<Project, bool>> ProjectFilterExpression(
    int creatorId, 
    int verticalMarketId, 
    int productCategoryId)
{
    Expression<Func<Project, bool>> projectFilterExpression = pfe => 
    !pfe.IsDeleted
    //CreatorId Filter
    && (creatorId.Equals(0) || pfe.CreatedBy.Equals(creatorId))
    //Vertical Market Filter
    && (verticalMarketId.Equals(0) || pfe.VerticalMarketsId.Equals(verticalMarketId))
    // Product Category Filter
    && (productCategoryId.Equals(0) || pfe.ProductCategoriesId.Equals(productCategoryId)); 
    return projectFilterExpression;
}
Run Code Online (Sandbox Code Playgroud)

然后我在过滤器方法中调用这个静态方法。

var filter = ProjectFilterExpression(CreatorId, VerticalMarketId, ProductCategoryId);
Run Code Online (Sandbox Code Playgroud)

最后我在 LINQ where 子句中应用了这个过滤器

getProjects = await _context.Projects.Where(filter).AsNoTracking().ToListAsync();
Run Code Online (Sandbox Code Playgroud)

它工作得很好。