Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic query building with entity framework core - Build a query "by steps"

I'm trying to make a class to perform a dynamic filters, depending on what parameters I'll send to its "filter" method but I'm facing some difficulties on building my query.

It's more easy to explain with my following code, where I'm simply trying to apply some filters basing on what i receive in input:

public class PeopleManager : Controller
    {
        private readonly MyPeopleContext _context;
        public PeopleManager(PeopleContext context)
        {
            _context = context;
        }

        public IEnumerable<Person> filter (int? id, string name, int? age)
        {
            var peoplequery = _context.People;
            if(id!=null)
            {
               peoplequery = peoplequery .Where(p => p.Id.Equals(id));
            }

            if(name!="")
            {
               peoplequery = peoplequery .Where(p => p.Name.Contains(name));
            }

            if(age!=null)
            {
               peoplequery  = peoplequery .Where(p => p.Age.Equals(age));
            }

            return peoplequery;
        }
    }

Obviously, my code is not working and according to this question that I've found:

Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Data.Entity.DbSet'

I've managed to edit my code as follows:

public IEnumerable<Person> filter (int? id, string name, int? age)
            {
                var people = _context.People;

                var peoplequery = from p in people select people;

                if(id!=null)
                {
                   peoplequery = peoplequery .Where(p => p.Id.Equals(id));
                }

                if(name!="")
                {
                   peoplequery = peoplequery .Where(p => p.Name.Contains(name));
                }

                if(age!=null)
                {
                   peoplequery  = peoplequery .Where(p => p.Age.Equals(age));
                }

                return peoplequery;
            }

But doing this, I can't access to people's properties like id, name, etc... in my lambda expressions.

How can I build this conditional query without any error?


1 Answers

I guess you want to have smth like this:

public class PeopleController : Controller
{
    private readonly MyPeopleContext _context;

    public PeopleManager(PeopleContext context)
    {
        _context = context;
    }

    public IEnumerable<Person> Filter (int? id, string name, int? age)
    {
        var peoplequery = _context.People.AsQueryable();
        if(id.HasValue)
        {
           peoplequery = peoplequery.Where(p => p.Id == id.Value);
        }
        if(!string.IsNullOrEmpty(name))
        {
           peoplequery = peoplequery.Where(p => p.Name.Contains(name));
        }
        if(age.HasValue)
        {
           peoplequery = peoplequery.Where(p => p.Age == age.Value);
        }

        return peoplequery.ToArray();
    }
}
like image 182
itim Avatar answered Oct 14 '25 22:10

itim