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



我正试图使用LINQ和Entity框架在我的应用程序中构建一个高级搜索,该框架依赖于10个参数,但用户可以发送一个或多个参数进行搜索。我很想用下面的方式实现它,但它没有起作用,而是设置if条件并在每次检查时更改查询。

那么,有没有什么简单的方法可以使用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();

实现这一点的简单方法是使用形式的where子句链接。与表达式树相比,我一直更喜欢这种方法,因为它简单明了。

假设所有谓词值都可以为null,下面是一个示例:

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子句,而忽略其余属性

您还可以在新的Filter对象中定义所有参数,并将这些"if"语句提取到自己的FilterStudents方法中,该方法采用IQueryable<学生>筛选作为参数。

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

一篇简单的文章,这里有一个例子

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

我不确定"simple",但是的,这是可能的。

这里的主要思想是为QueryAble.Where()方法创建一个表达式树。

public class SearchedTerms
{
    public string FirstName {get;set;}
    ...
    public int Age {get;set;}
}
public Expression<Func<Student,bool>> GetPredicateExpression(SearchedTerms terms)
{
    // ...
}

相关内容

  • 没有找到相关文章

最新更新