EF4搜索页面可选字段与lambdas

时间:2012-05-29 12:50:11

标签: asp.net-mvc-3 entity-framework lambda

我已经回顾了已经在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语句。想象一下,用户选择foobaz并将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查询

3 个答案:

答案 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; 
}

希望这会有所帮助。