在EF 5.0中链接OR条件

Vul*_*ary 7 c# linq entity-framework

我将在前面加上我正在积极寻找解决这个问题的方法,但我想如果有人在堆栈上找到这个问题,我可能会缩短一些研究和开发时间.(我在网上找不到任何东西,所以这里有)

我们在构建的应用程序框架中有一个案例,我们需要能够接受一组Predicates(List<Expression<Func<T,bool>>>)并在搜索框架中解析它.

现在我们有能力以这种方式过滤:

//Assume predicates is passed as a method argument.
//     of List<Expression<Func<T,bool>>>
//Assume user is passed in as a method argument.
//Assume FilterToUserAccess is a custom extension method that restricts the dataset
//    to access restrictions.
var query = _dbContext.Set<EntityType>()
     .FilterToUserAccess(user);
foreach(var p in predicates){
     query = query.Where(p);
}

return p.ToList();
Run Code Online (Sandbox Code Playgroud)

我们需要这样做的原因是可过滤对象的可扩展性.但是,对于快速搜索,鉴于EF的内置功能,这是不可能的.我需要做的是:

对象A(让我们假装它是一辆赛车),我们想在快速搜索框中搜索品牌,型号,团队和驱动程序.因此,如果我输入"Earnhardt",它将搜索所有赛车实体属性,包括品牌,型号,团队和驱动程序.我最终会得到所有的DEI汽车以及Dale Jr.我想使用相同的方法,因此我们可以配置一个可搜索的实体并在应用程序启动时反映搜索配置.理想情况下,我想让查询看起来像这样:

//Assume predicates is passed as a method argument.
//     of List<Expression<Func<T,bool>>>
//Assume user is passed in as a method argument.
//Assume FilterToUserAccess is a custom extension method that restricts the dataset
//    to access restrictions.
var query = _dbContext.Set<EntityType>()
    .FilterToUserAccess(user);
foreach(var p in predicates){
    query = query.Or(p);
}

return p.ToList();
Run Code Online (Sandbox Code Playgroud)

我意识到我能做到:

_dbContext.Set<EntityType>().Where(predicate1 || predicate2 || predicate3)
Run Code Online (Sandbox Code Playgroud)

但是,这对我们想要解决此问题的方法不起作用.理想情况下,我们的一个客户端站点的管理员可以进入并配置一个额外的搜索词,只需单击即可包含在该实体类型的任何和所有快速搜索中,就像我们目前可以使用标准的过滤器一样.Where(...)"和"链接逻辑.

Vul*_*ary 6

第一个解决方案是破产,但是通过更多的挖掘,有一个非常简单的解决方案,经过验证和工作.

第1步:为LinqKit安装NuGet包.

第2步:享受下面的代码

using (ISampleRepository repo = new SampleRepository())
{
    var predicates = new List<Expression<Func<Customer,bool>>>(){
        (x => x.FirstName.Contains(searchValue)),
        (x => x.LastName.Contains(searchValue))
    };

    var lambda = PredicateBuilder.False<Customer>();
    lambda = predicates.Aggregate(lambda, (current, p) => current.Or(p).Expand());

    var query = repo.QueryCustomers().AsExpandable().Include(x => x.Phones).Where(lambda);
    return query.Take(500)
        .ToList()
        .Select(x => x.ToDTO())
        .ToList();
}
Run Code Online (Sandbox Code Playgroud)

这只是尖峰样本,但是使用 - >的方法做同样的事情

List<T> QuickSearch<T>(string input) ...
Run Code Online (Sandbox Code Playgroud)

将能够使用相同的方法.您仍然以传递的Expression形式存在一组谓词,然后使用谓词构建器技巧来关闭查询.然后使用AsExpandable()允许您执行使用谓词构建器创建的组合谓词.

希望这不仅仅对我有帮助,但这是我要使用的解决方案,因为它的代码要少得多.允许您在其他地方构建谓词...并且在事实之后仍然将它们组合在"OR"语句中.