我已经回顾了已经在SO上提出的一些问题并尝试了谷歌,但却没有将其付诸实践。我有一个搜索页面,用户可以在其中输入并选择0到10个字段填写的下拉列表。 (可以返回“全部”结果)。它有效,直到我有一个允许多个选择的字段
<select name="area" size="25" multiple="multiple">
<option>foo</option>
<option>bar</option>
<option>baz</option>
<!--blah blah blah-->
</select>
<input name="someField"/>
我无法将其翻译成EF lambda语句。想象一下,用户选择foo
和baz
并将42
输入someField
框。搜索应返回area
的结果,并且someField
具有正确的值。
//...
var entities = db.entities;
//... this is inside of a switch/loop through the forms collection
string value = Request.Form[key];
//...
If (area <> "") {
string[] areaSplit = value.Split(',');
foreach (string s in subSplit)
{
string temp = s;
entities.Where(x => x.area.Contains(temp)); //1
}
}
//...
entities.Where(x => x.someField == value);
所以//1
所在的地方不应该是排他性的。换句话说,entities.area
可以包含表单字段area
中的任何一个值。在SQL查询中,我可能会写
... someField = 42 and (area = 'foo' or area = 'baz')
改为编写SQL查询是否更好(高效,最佳实践)?
使用谓词构建器编辑
var outer = PredicateBuilder.True<entity>();
var inner = PredicateBuilder.False<entity>();
//... this is inside of a switch/loop through the forms collection
string value = Request.Form[key];
//...
string[] areaSplit = value.Split(',');
foreach (string s in subSplit)
{
string temp = s;
inner = inner.Or(x => x.area.Contains(temp)); //1
}
//..
outer = outer.And(x => x.someField == value);
//...end of loop
outer.And(inner.Expand());
var foo = db.entity.AsExpandable().Where(outer.Expand());
然而,它似乎忽略了inner
部分。 SQL事件探查器不显示inner
查询
答案 0 :(得分:1)
您可以反过来使用Contains
:
string[] areaSplit = value.Split(',');
entities = entities.Where(x => areaSplit.Contains(x.area)); //1
entities = entities.Where(x => x.someField == value);
这将在sql中的IN
子句中翻译:
WHERE (area IN (N'foo', N'baz')) AND (42 = someField)
答案 1 :(得分:0)
Eonasdan,
我建议您从以下位置查看谓词构建器:
http://www.albahari.com/nutshell/predicatebuilder.aspx
这是构建动态过滤器的一种非常好的综合方式,与您描述完全相同。
答案 2 :(得分:-1)
Eonasdan,
在返回查询结果的方法
中public virtual ActionResult QueryWithMultipleParameters(int param1, int param2, int param3, ...)
{
var query = dataContext.EntityToQuery;
if(param1 > 0)
{
query = query.Where(e => e.param1 == param1);
}
if(param2 > 0)
{
query = query.Where(e => e.param2 == param2);
}
.... etc.
return query;
}
希望这会有所帮助。