Filtering DbContext data dynamically by user input in WPF applications I need to filter database data based on filters available to the end user in the form of search term text box, select boxes etc.

I have put together this code and need feedback if this is a good way to do it or if there are any better solutions.

using Multi.Model;
using System;
using System.Linq;
using System.Windows.Controls;

namespace Multi.Pages
{
    /// &lt;summary&gt;
    /// Interaction logic for Page1.xaml
    /// &lt;/summary&gt;
    public partial class Page1 : Page
    {

        public Page1()
        {
            InitializeComponent();
            textBoxName.TextChanged += TextBoxName_TextChanged;
            PopulateDataGrid();
        }

        private void PopulateDataGrid()
        {
            using (var db = new optisysEntities())
            {
                var items = db.clients.AsQueryable();
                items = FilterClients(db, items);
                dataGrid.ItemsSource = items.ToList();
            }
        }

        private System.Linq.IQueryable&lt;Multi.Model.clients&gt; FilterClients(optisysEntities db, System.Linq.IQueryable&lt;Multi.Model.clients&gt; clients)
        {

            if (!String.IsNullOrWhiteSpace(textBoxName.Text)) clients = db.clients.Where(c =&gt; c.name.Contains(textBoxName.Text)
                                                                                  || c.phone.Contains(textBoxName.Text));
            // if (!String.IsNullOrWhiteSpace(search.Email)) clients = clients.Where(u =&gt; u.Email.Contains(search.Email));
            // if (search.UsertypeId.HasValue) clients = clients.Where(u =&gt; u.UsertypeId == search.UsertypeId.Value);
            return clients;
        }

        private void TextBoxName_TextChanged(object sender, TextChangedEventArgs e)
        {
            PopulateDataGrid();
        }

    }
}
Reducing your code to what I think is the core of your question:

private System.Linq.IQueryable&lt;Multi.Model.clients&gt; FilterClients(optisysEntities db, System.Linq.IQueryable&lt;Multi.Model.clients&gt; clients)
{

    if (!String.IsNullOrWhiteSpace(textBoxName.Text)) 
        clients = db.clients.Where(c =&gt; c.name.Contains(textBoxName.Text) || c.phone.Contains(textBoxName.Text));

    if (!String.IsNullOrWhiteSpace(search.Email)) 
        clients = clients.Where(u =&gt; u.Email.Contains(search.Email));

    if (search.UsertypeId.HasValue) 
        clients = clients.Where(u =&gt; u.UsertypeId == search.UsertypeId.Value);

    return clients;
}


Yes, this is one of the better ways to do dynamic filtering.



I would suggest abstracting the data retrieval into a separate layer. You don't want your form logic handling your underlying ORM directly.

This is exacerbated by the fact that you've put the FilterClients() method by itself. Your UI form therefore contains a method whose reponsibility has nothing to do with the UI.

However, I get the feeling that this application is either tiny, or has only just been developed. So I can understand that this abstraction is something for a later stage. I would suggest doing it immediately to make it less painful in the future, but that's your choice.