实体框架核心-动态过滤

时间:2018-08-23 08:53:07

标签: c# entity-framework-core filtering

我在使用Entity Framework Core从数据库检索正确的结果时遇到问题。

这是我的Article桌子:

enter image description here

我想使用IQueryable创建动态过滤器,该过滤器将返回以下结果:

Select a.Id, a.Name, a.BrandId, a.GenderId
from dbo.Articles a
where GenderId in (1)
  and BrandId in (1, 2, 3)

返回:

enter image description here

这是我的控制器操作:

public async Task<IActionResult> Clothes()
{
    var model = new ArticleFilterViewModel();
    model.Genders.AddRange(new int[1] { 1 });
    model.Brands.AddRange(new int[3] { 1, 2, 3 });
    var result = await articleSerivce.GetFilteredUsers(model);
    return View(result);
}

这是我用于获取已过滤文章的存储库方法:

public ICollection<Article> GetFilteredUsers(ArticleFilter filter)
{
    var articles = GetAll();
    articles = FilteredByBrand(articles, filter.Brands);
    articles = FilteredByGender(articles, filter.Genders);
    var result = articles.ToList();
    return result;
}

IQueryable<Article> FilteredByBrand(IQueryable<Article> articles,  List<int> items)
{
    return articles.WhereIf(items.IsNotNullOrEmpty(),  x => items.Contains(x.BrandId));
}

IQueryable<Article> FilteredByGender(IQueryable<Article> articles, List<int> items)
{
     return articles.WhereIf(items.IsNotNullOrEmpty(), x => items.Contains(x.GenderId));
}

执行此代码后,我得到以下信息:

enter image description here

我得到的结果是3篇文章,而不是2篇(文章ID:2、3、2)。

知道我在做什么错吗?

2 个答案:

答案 0 :(得分:1)

我不知道您的WhereIf()方法做什么或您从GetAll()的实际收获,但是如果我将WhereIf()替换为Where(),它将按预期工作。

private IQueryable<Article> FilteredByBrand(IQueryable<Article> articles, List<int> items)
{
    return items.IsNullOrEmpty() ? articles : articles.Where(x => items.Contains(x.BrandId));
}

private IQueryable<Article> FilteredByGender(IQueryable<Article> articles, List<int> items)
{
    return items.IsNullOrEmpty() ? articles : articles.Where(x => items.Contains(x.GenderId));
}

返回

  

2-酷T恤-2-1-
  3-黄色内裤-3-1-

Here is my complete repro code.

答案 1 :(得分:1)

使用EF Core,请尝试此操作。

简单高效的动态过滤器

public static List<Inventory> GetAll(string po, string cod)
{
    using (var context = new ApplicationDbContext())
    {
        var Items = context.Inventorys
            .Where(p => p.CodigoPO == po || po == string.Empty)
            .Where(p => p.CodigoProduto == cod || cod == string.Empty).ToList();
        return Items;
    }
}

Generated by EF Core, using only the PO parameter Generated by EF Core, using only the PO parameter