我正在尝试使用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();
答案 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)
{
// ...
}