使用linq和Entityframework实现高级搜索的最佳实践

时间:2016-07-23 13:33:39

标签: c# entity-framework linq

我正在尝试使用LINQ和Entity框架在我的应用程序中构建高级搜索,具体取决于10个参数,但用户可以发送一个或多个参数进行搜索。我厌倦了像以下方式那样实现它,但它没有工作,而不是在条件和每次检查时更改查询。

那么有没有简单的方法可以根据用户输入使用LINQ进行选择以匹配结果?

var data = (from item in db.Student
           where item.Firstname == fname
           && item.Middlename == mname
           && item.Lastname == lname
           && item.Birthday == birthday
           && item.Age == age
           && item.AdmissionYear == year
           && item.Grade == grade
           && item.Address == Address
           && item.Class == class
           && item.Number == number
           select item).FirstOrDefault();

3 个答案:

答案 0 :(得分:2)

您可以使用并构建表达式树,它将根据您传递的参数动态构建过滤子句

这里有一个简单的文章

http://www.codeproject.com/Tips/582450/Build-Where-Clause-Dynamically-in-Linq

您还可以使用PredicateBuilder

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

所以你会有这样的东西

IQueryable<Product> SearchProducts (params string[] keywords)
{
  var predicate = PredicateBuilder.False<Product>();

  foreach (string keyword in keywords)
  {
    string temp = keyword;
    predicate = predicate.Or(p => p.Description.Contains (temp));
  }
  return dataContext.Products.Where (predicate);
}

答案 1 :(得分:2)

实现此目的的简单方法是使用 where子句链接的形式。由于它的简单和清晰,我一直更喜欢这种方法而不是表达树。

假设所有谓词值都可以为空,这里有一个例子:

var query = db.Student.AsQueryable();

if (age != null)
    query = query.Where(s => s.Age == age.Value);
if (fname != null)
    query = query.Where(s => s.Firstname == fname);
if (lname != null)
    query = query.Where(s => s.Lastname == lname);

// etc...

var student = query.FirstOrDefault();

这样,您可以仅使用用户传入的属性动态构建where子句,而忽略其余属性。

您还可以在新的过滤器对象中定义所有参数,并提取这些&#34;如果&#34;声明到他们自己的 FilterStudents 方法中,该方法将 IQueryable&lt; Student&gt; Filter 作为参数。

答案 2 :(得分:0)

我不确定&#39;简单&#39;但是,是的,这是可能的。

这里的主要想法是为QueryAble.Where()expression tree创建method

public class SearchedTerms
{
    public string FirstName {get;set;}
    ...
    public int Age {get;set;}
}

public Expression<Func<Student,bool>> GetPredicateExpression(SearchedTerms terms)
{
    // ...
}
相关问题