如何简化此Entity Framework代码?

时间:2014-06-14 22:04:43

标签: c# linq entity-framework entity-framework-4

我有一个复杂的搜索功能,允许用户从字段列表中进行选择,然后选择搜索值和修改器。例如,如果这是购物车,则用户正在搜索产品并可以搜索匹配的产品:

名称包含" ball" 价格低于" 5.00" 运出"美国"

等。

我的问题是,我有25个不同的字段要搜索,有些是与子孙对象有关的复杂字体。因此,对于每个字段,我都有一个if结构,如:

if (mod == "!=")
{
    allInvestigators = allInvestigators.Where(i => !i.Indicators.Any(j => j.Title.ToLower().Contains(txtVal)));
}
else if (mod == "==")
{
    allInvestigators = allInvestigators.Where(i => i.Indicators.Any(j => j.Title.ToLower() == txtVal));
}
else
{
    allInvestigators = allInvestigators.Where(i => i.Indicators.Any(j => j.Title.ToLower().Contains(txtVal)));
}

所以为了说清楚,用户可以选择一个字段,一个搜索修饰符(==,<,>,!=),并且可以在一次搜索中使用其中的几个过滤器!有没有人对如何缩小此代码有任何想法?

更新这就是我现在的位置..

allInvestigators = allInvestigators.Where(i => 
                                (i.Address.State.ToLower().Contains(txtVal) && mod == "=") ||
                                (i.Address.State.ToLower() == txtVal && mod == "==") ||
                                (i.Address.State.ToLower() != txtVal && mod == "!=")
                            );

3 个答案:

答案 0 :(得分:2)

您可以尝试将字段查询放入变量列表中,并且可以循环使用它们并正确应用它们。不是完整的代码,只是为了灵感:

Expression<Func<Item, Boolean>> expr = j => j.Title.ToLower().Contains(txtVal);
allInvestigators = allInvestigators.Where(i => !i.Indicators.AsQueryable().Any(expr));

答案 1 :(得分:1)

查看“Nutshell中的C#4.0 / 5.0”中描述的PredicateBuilder

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;

public static class PredicateBuilder
{
  public static Expression<Func<T, bool>> True<T> ()  { return f => true;  }
  public static Expression<Func<T, bool>> False<T> () { return f => false; }

  public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
                                                      Expression<Func<T, bool>> expr2)
  {
    var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
    return Expression.Lambda<Func<T, bool>>
          (Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
  }

  public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
                                                       Expression<Func<T, bool>> expr2)
  {
    var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
    return Expression.Lambda<Func<T, bool>>
          (Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
  }
}

它可以用于首先构建Expression / Specification

您可以在博文Specifications Pattern with LINQ中找到与AndSpecification想法类似的OrSpecificationNotSpecificationPredicateBuilder的示例。

答案 2 :(得分:0)

您可以使用String.Equals

allInvestigators = allInvestigators.Where(i => 
                            (i.Address.State.ToLower().Contains(txtVal) && mod == "=") ||
                            (i.Address.State.Equals(txtVal, StringComparison.CurrentCultureIgnoreCase) && mod == "==") ||
                            (!i.Address.State.Equals(txtVal, StringComparison.CurrentCultureIgnoreCase) && mod == "!=")
                        );