Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有多个未知条件的Where子句_C#_.net_Sql Server_Linq_Asp.net Mvc 4 - Fatal编程技术网

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