Filter Producs by any property I have Products table which looks like this:



I have some data in this table and I want to filter it depending on this columns (Filtering with columns type of string isn't problem). For this I have the code (in ASP.NET Core Web API Project) shown below. I know it's not a good approach. I have another table which has more foreign keys, so it will be more difficult to do this kind of work on it.

In SearchProduct action method I am getting the product object, which properties have specific values. For example, If Name="Box", then I want to get products from the product list, which Name is "Box" too.

The consumer of this service is WPF application, where I have the window, where the controls (textboxes and comboboxes{ for productType and ProductUnit}) are placed and the user will be able to search data with any criteria. For example, if he wants to search only with Name, he will write something only in Name textbox. If he wants to search product which name is "Box" and also the productType is "A", then he will write "Box" in name textbox and will choose A type in comboBox.

P.S When product is added in this table, if user doesn't write anything in the Name textbox for example, the value of Name will be "" and not null.

    [HttpPost("SearchProduct")]
    public IEnumerable&lt;Product&gt; SearchProduct([FromBody]Product product)
    {
        IEnumerable&lt;Product&gt; data;

        if(product.ProductTypeID != null &amp;&amp; product.ProductUnitID != null)
        {
            data = _context.Products.Where(x =&gt;
          x.Name.Contains(product.Name) &amp;&amp;
          x.Code.Contains(product.Code) &amp;&amp;
          x.Barcode.Contains(product.Barcode) &amp;&amp;
          x.InnerCode.Contains(product.InnerCode) &amp;&amp;
          (x.ProductTypeID == product.ProductTypeID &amp;&amp;
          x.ProductUnitID == product.ProductUnitID))

           .Include(x =&gt; x.ProductType)
           .Include(x =&gt; x.ProductUnit);
        }
        else if(product.ProductTypeID == null &amp;&amp; product.ProductUnitID == null)
        {
            data = _context.Products.Where(x =&gt;
        x.Name.Contains(product.Name) &amp;&amp;
        x.Code.Contains(product.Code) &amp;&amp;
        x.Barcode.Contains(product.Barcode) &amp;&amp;
        x.InnerCode.Contains(product.InnerCode) ||
        (x.ProductTypeID == product.ProductTypeID &amp;&amp;
        x.ProductUnitID == product.ProductUnitID))

         .Include(x =&gt; x.ProductType)
         .Include(x =&gt; x.ProductUnit);
        }
        else if(product.ProductTypeID != null)
        {
            data = _context.Products.Where(x =&gt;
        x.Name.Contains(product.Name) &amp;&amp;
        x.Code.Contains(product.Code) &amp;&amp;
        x.Barcode.Contains(product.Barcode) &amp;&amp;
        x.InnerCode.Contains(product.InnerCode) &amp;&amp;
        x.ProductTypeID == product.ProductTypeID)

         .Include(x =&gt; x.ProductType)
         .Include(x =&gt; x.ProductUnit);
        }
        else
        {
            data = _context.Products.Where(x =&gt;
        x.Name.Contains(product.Name) &amp;&amp;
        x.Code.Contains(product.Code) &amp;&amp;
        x.Barcode.Contains(product.Barcode) &amp;&amp;
        x.InnerCode.Contains(product.InnerCode) &amp;&amp;
        x.ProductUnitID == product.ProductUnitID)

         .Include(x =&gt; x.ProductType)
         .Include(x =&gt; x.ProductUnit);
        }



        return data;
    }
You code seems to contradict your text. You say:


  For example, if he wants to search only with Name, he will write something only in Name textbox. If he wants to search product which name is "Box" and also the productType is "A", then he will write "Box" in name textbox and will choose A type in comboBox.


And yet each method seems to contain multiple Where clauses.

Wouldn't it be more flexible to construct an IQueryable&lt;T&gt;? Something along these lines:

private IQueryable&lt;Product&gt; GetProductsQueryable(Product request)
{
    var queryable = _dbContext.Products.AsQueryable();

    if (!string.IsNullOrEmpty(request.Name))
    {
        queryable = queryable.Where(x =&gt; x.Name.Contains(request.Name));
    }

    if (!string.IsNullOrEmpty(request.Code))
    {
        queryable = queryable.Where(x =&gt; x.Code.Contains(request.Code));
    }

    if (!string.IsNullOrEmpty(request.Barcode))
    {
        queryable = queryable.Where(x =&gt; x.Barcode.Contains(request.Barcode));
    }

    return queryable;
}