【问题标题】:EF4 search page optional fields with lambdas带有 lambda 的 F4 搜索页面可选字段
【发布时间】:2012-05-29 12:50:10
【问题描述】:

我已经查看了一些关于 SO 的问题,并尝试了 Google,但未能使其正常工作。我有一个搜索页面,用户可以在其中输入和选择下拉列表,其中填写了 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 查询

【问题讨论】:

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


    【解决方案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)
    

    【讨论】:

      【解决方案2】:

      伊奥纳斯丹,

      我建议您从以下位置查看谓词构建器:

      http://www.albahari.com/nutshell/predicatebuilder.aspx

      这是一种非常好的综合方法,可以完全按照您的描述构建动态过滤器。

      【讨论】:

      • 我之前确实尝试过谓词生成器。我已经用我的尝试更新了我的问题
      【解决方案3】:

      伊奥纳斯丹,

      在返回查询结果的方法中

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

      希望这会有所帮助。

      【讨论】:

      • 这就是我已经在做的事情,但正如我所指出的,多选字段不包含 all 选定的值。每个结果都将选择 一个 选项。此方法将简单地对其进行过滤,期望该列具有所有值
      • @Eonasdan 没有注意到这一点。对不起。我假设您可以选择“全部”,其值为 0。
      • 嗯,是的,该字段有一个“全部”选项,但这不是问题。问题是查询数据库应该返回多行。 area 列应返回包含任何选定选项的行
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-15
      • 2022-06-27
      • 2021-01-28
      • 1970-01-01
      相关资源
      最近更新 更多