Amr Ramadan
Amr Ramadan

Reputation: 1267

Best practices to implement Advanced search using linq and Entityframework

I am trying to build an advanced search in my application using LINQ and Entity framework depending on 10 parameters but the user have the ability to send one or more parameter for search. I tired to implement it like the below way but it didn't work instead of making if conditions and change the query every check.

So is there any simple way to use LINQ to select depending on the user inputs to match results exists?

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

Upvotes: 2

Views: 3529

Answers (3)

Milos Mrdovic
Milos Mrdovic

Reputation: 1471

The easy way of implementing this is using a form of where clause chaining. I have always preferred this approach over the expression trees because of it's simplicity and clarity.

Assuming that all your predicate values are nullable, here's an example:

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

This way you can dynamically build your where clause using only the properties that your user passed in, while ignoring the rest.

You can also define all your parameters in a new Filter object and extract these "if" statements into their own FilterStudents method which take IQueryable<Student> and Filter as arguments.

Upvotes: 2

Pavel Voronin
Pavel Voronin

Reputation: 13995

I am not sure about 'simple', but yes, it is possible.

The main idea here is to create an expression tree for a QueryAble.Where() method.

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

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

Upvotes: 0

Hassan
Hassan

Reputation: 1433

You could use and build an expression tree, which will build dynamically your filtering clause based on the parameters your are passing

A simple article with an example here

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

You could also use the PredicateBuilder Class

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

So you will have something like this

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

Upvotes: 2

Related Questions