C# 具有多个未知条件的Where子句
我目前正在为我的公司开发一个员工管理系统。字段可能会随时间变化,因此我为每个字段提供了如下界面:C# 具有多个未知条件的Where子句,c#,.net,sql-server,linq,asp.net-mvc-4,C#,.net,Sql Server,Linq,Asp.net Mvc 4,我目前正在为我的公司开发一个员工管理系统。字段可能会随时间变化,因此我为每个字段提供了如下界面: public interface IStaffInfoField { // ... IQueryable<Staff> Filter(IQueryable<Staff> pList, string pAdditionalData); // ... } 现在,用户希望使用多种条件进行搜索,这很简单,我只需遍历列表并调用过滤器。然而,他们也需要一
public interface IStaffInfoField
{
// ...
IQueryable<Staff> Filter(IQueryable<Staff> pList, string pAdditionalData);
// ...
}
现在,用户希望使用多种条件进行搜索,这很简单,我只需遍历列表并调用过滤器
。然而,他们也需要一个或条件(例如,员工姓名a
,或姓名B
,部门名称C
,或年龄30
)注意:用户是最终用户,他们通过组合框和文本框输入搜索查询。
我可以通过某种方式修改模式或lambda表达式来实现这一点吗?因为在整个过程中,我不会保存原始列表以将其合并为条件。我认为如果我保存表达式并将其合并为或条件,则速度会很慢
我现在能想到的唯一解决方案是向需要原始SQLWHERE语句的接口添加一个方法。但是我的整个程序还没有使用纯SQL查询,现在使用它不好吗?由于您的方法返回IQueryable
,客户端已经可以使用它进行任意复杂的查询了
IQueryable<Staff> result = xxx.Filter( .... );
result = result.Where( ... );
if ( ... )
result = result.Where( s => ( s.Age > 30 || s.Salary < 1 ) && s.Whatever == "something" );
IQueryable结果=xxx.Filter(…);
结果=结果,其中(…);
如果(…)
结果=结果。其中(s=>(s.年龄>30 | | s.薪水<1)和s.任何东西==“某物”);
IQueryable
非常灵活。当您开始枚举结果时,将计算查询树并将其转换为sql
我只是想知道你为什么需要这个界面?!由于您的过滤器
方法需要IQueryable
,这意味着客户端已经拥有IQueryable
!如果她已经可以自己应用任意复杂的查询运算符,那么她为什么要调用你的过滤器方法呢
编辑:
在您进一步解释之后,如果我是您,我将创建一个简单的界面,让用户创建自己的包含OR和and子句的查询树,并创建一个简单的函数,将用户查询树转换为linq表达式树
换句话说,不要让最终用户在linq查询树级别上工作,这太抽象了,也太危险了,不能让用户接触到代码的底层。但是,手动将抽象树转换为linq树听起来既安全又简单。您可以下载Albahari的。它包含一个函数,允许您将LINQ表达式与或以动态方式连接在一起
var predicate = PredicateBuilder.False<Staff>();
predicate = predicate.Or(s => s.Name.Contains(data));
predicate = predicate.Or(s => s.Age > 30);
return dataContext.Staff.Where(predicate);
var predicate=PredicateBuilder.False();
谓词=谓词。或(s=>s.Name.Contains(data));
谓词=谓词或(s=>s.Age>30);
返回dataContext.Staff.Where(谓词);
您还可以下载源代码并查看其实现方式。如果您的用户是最终用户,并且他们通过UI输入条件,则您可能需要查看支持IQueryable的UI控件。Telerik有大量预烘焙控件。在大多数情况下,最终用户与网格交互,并对列应用过滤器。还有其他几个供应商也做同样的事情
第二种选择是,如果你想让你的生活变得困难,你可以把用户提供的输入文本解析成一个表达式树,然后把这个表达式树映射到一个IQueryable。如果您不熟悉解析器,此任务将很难实现。对不起,用户是最终用户,而不是开发人员。向最终用户提供了一个组合框和文本框列表,用于输入他们的搜索查询。这就是为什么我还不知道表达式的原因(在你的例子中,`s=>(s.Age>30 | | s.Salary<1)&&s.whatch==“something”`我是需要生成这样的表达式的人,这就是为什么我需要接口(因为字段未知,也许明天他们想要管理他们的员工关系,谁知道呢).这些小细节改变了一切:)是的!这是我想做的,但我不知道如何实现它。非常感谢你!
var predicate = PredicateBuilder.False<Staff>();
predicate = predicate.Or(s => s.Name.Contains(data));
predicate = predicate.Or(s => s.Age > 30);
return dataContext.Staff.Where(predicate);