EF 5.0中的链接OR条件 [英] Chaining OR conditions in EF 5.0

查看:62
本文介绍了EF 5.0中的链接OR条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将以我正在积极寻找该问题的解决方案的方式作为开头,但是我认为,如果有人在堆栈上已经弄清楚了这一点,那么我可能会缩短一些研发时间.(我在网上什么都没找到,所以去吧)

I will preface this with I'm actively searching for the solution to this problem but figured I might short cut some research and development time if someone here on stack has already figured this out. (I have found nothing online so here goes)

在我们正在构建的应用程序框架中有一个案例,其中我们需要能够接收一组谓词( List< Expression< Func< T,bool>> )并且在搜索框架中对其进行解析.

We have a case in an application framework we are building where we need the capability to take in a set of Predicates (List<Expression<Func<T,bool>>>) and parse it in a search framework.

现在,我们可以通过以下方式进行过滤:

Right now we have the capability to filter in this way being that:

//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();

我们需要这样做的原因是为了可过滤对象的可伸缩性.但是,鉴于EF的内置功能,无法进行快速搜索.我需要做的是:

The reason we need to do this is for scale-ability of filterable objects. However for a quick search this is not possible given the built in capabilities of EF. What I need to be able to do is:

对象A(假设它是赛车),我们想在快速搜索框中搜索品牌,型号,车队和车手.因此,如果输入"Earnhardt",它将搜索所有赛车实体的属性,包括制造商,模型,车队和车手.最后,我将使用所有DEI汽车以及DaleJr.我想使用相同的方法,以便我们可以配置可搜索实体并在应用程序启动时反映搜索配置.理想情况下,我想采取某种方式使查询看起来与此类似:

Object A (lets pretend it's a race car) and we want to search make, model, team, and driver in a quick search box. So if I enter "Earnhardt", it would search all race car entity properties being make, model, team, and driver. I would end up with all the DEI cars as well as Dale Jr. I would like to use the same approach so we can configure a searchable entity and reflect the search configuration on application start. I would ideally like to make some way of having the query look similar to this:

//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();

我意识到我可以做到:

_dbContext.Set<EntityType>().Where(predicate1 || predicate2 || predicate3)

但是,这不适用于我们要解决此问题的方法.理想情况下,我们客户站点之一的管理员将能够进入并配置一次额外的搜索词,只需单击一下即可将该实体类型的任何和所有快速搜索包括在内,例如我们目前可以使用使用标准的过滤器 .Where(...)和"链接逻辑.

However this will not work for the approach we want to take to solve this problem. Ideally an admin for one of our client sites would be able to go in and configure an additional search term with a single click to be included in any and all quick searches for that entity type like we can currently pull off with Filters which use the standard .Where(...) "and" chaining logic.

推荐答案

第一个解决方案是破产,但是通过进一步挖掘,找到了一个非常简单的解决方案,经过验证并可以使用.

First solution was a bust, however with some more digging there is an incredibly simple solution, verified and works.

步骤1 :为LinqKit安装NuGet软件包.

Step 1: install the NuGet package for LinqKit.

第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();
}

这只是加标样本,但使用->

This is just the spike sample but doing the same thing with a method taking in ->

List<T> QuickSearch<T>(string input) ...

将能够使用相同的方法.您仍然以传入的Expression形式收集谓词的集合,然后使用谓词构建器的技巧来进行查询.然后,使用AsExpandable()可以执行使用谓词构建器创建的组合谓词.

Will be able to use the same approach. You have a collection of predicates still in Expression form passed in, then you use the predicate builder tricks to pull the query off. Then using the AsExpandable() allows you to execute the combined predicate created using the predicate builder.

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

Hopefully this is helpful to more than just me, but this is the solution I'm going with as it's quite a bit less code. Allows you to build your predicates elsewhere... and still combine them in an "OR" statement after the fact.

这篇关于EF 5.0中的链接OR条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆