C语言中的动态Where子句lambdas

我有一个看起来像这样的搜索表单:

搜索表单

表单背后的代码如下所示:

@using (Html.BeginForm()) { @Html.ValidationSummary() 
@Html.DropDownList("SelectedType", Model.TypeOptions) @Html.DropDownList("SelectedSearch", Model.SearchOptions) @Html.TextBoxFor(x => x.SearchTerm)
}

我想要做的是从返回选项动态构造一个lambda where子句。 例如,如果用户选择“Process No”和“Contains”,那么lambda看起来就像

 model.DataSource = _db.InstrumentLists.Where(x => x.Process_No.Contains(SearchTerm)); 

或者,如果用户选择“PLC No”和“Equals”,那么lambda看起来就像

 model.DataSource = _db.InstrumentLists.Where(x => x.PLC_No == SearchTerm); 

我试图这样做,同时避免大案例陈述或if堆栈,即我不想要以下内容:

 if (SelectedType == "Process No" And SelectedSearch = "Contains") model.DataSource = _db.InstrumentLists.Where(x => x.Process_No.Contains(SearchTerm)); elseif (SelectedType == "Process No" And SelectedSearch = "Equals") model.DataSource = _db.InstrumentLists.Where(x => x.Process_No == SearchTerm); ... 

本质上我想传递一个类属性的引用,一些指定测试类型(即包含,等于,开始等)和一个函数的搜索项,或沿着这些行的东西,并返回一个谓词放置进入我的Where子句。 我希望这个函数动态工作,所以我不必为每个属性和测试类型的组合修改它。

这是可能的,还是使用字符串谓词参数的唯一方法?

编辑 :如果它很重要,我使用EF作为我的数据模型,所以_db.InstrumentLists返回一个ObjectSet

你有两个选择:

  • 制作一个基于“开关”的搜索方法,即根据用户选择的值执行不同的Where并返回一个DataSource

  • 使用Dynamic Linq并从字符串构造Where

编辑 – 动态Linq的示例:

 model.DataSource = _db.InstrumentLists.Where(SelectedType + " == @0", SearchTerm); 

利用谓词butilder动态构造where子句。

查看本文了解deatil: 使用Linq进行动态查询 。

示例:

  var predicate = PredicateBuilder.True(); if(!string.IsNullOrEmpty(txtAddress.Text)) predicate = predicate.And(e1 => e1.Address.Contains(txtAddress.Text)); if (!string.IsNullOrEmpty(txtEmpId.Text)) predicate = predicate.And(e1 => e1.Id == Convert.ToInt32(txtEmpId.Text)); EmployeeDataContext edb= new EmployeeDataContext(); var emp = edb.Employees.Where(predicate); grdEmployee.DataSource = emp.ToList(); grdEmployee.DataBind(); 

从我的头顶(我现在不能尝试……):

 public bool GetComparativeFunction(String property, SearchModel options) { if (options.SelectedSearch == "Contains") return property.Contains(options.SearchTerm); if (options.SelectedSearch == "Equals") return property.Equals(options.SearchTerm); return false; //default option } public Expression> GetLambdaExpressionFromFilter(SearchModel options) { if (options.SelectedType == "Process_No") return p => GetComparativeFunction(p.Process_No, options); if (options.SelectedType == "PLC_No") return p => GetComparativeFunction(p.PLC_No, options); return p => true; //default option } 

然后在您的查询中:

 model.DataSource = _db.InstrumentLists.Where(GetLambdaExpressionFromFilter(Model)); 

我不确定它是否适用于IQueryable <>但如果你可以使用IEnumerable <>你可以随时删除Expression <>部分