title: Is it a good practice to pass IQueryable as parameter in a Service layer method?
body: <p>I have an ASP.NET application with 3 layers <strong>UI</strong>, <strong>Service Layer</strong> and <strong>Repository</strong>.</p>
  
  <p>I have to implement a <strong>search functionality</strong> on the products in the database. 
  <code>ProductRepository</code> is my <strong>repository class</strong> and the signature of the method that gets all the <strong>products</strong> from the database is:</p>
  
  <pre><code>IQueryable&lt;Product&gt; GetAllProducts();
  </code></pre>
  
  <p>Therefore from my <strong>Service Layer</strong> I use:</p>
  
  <pre><code>IProductRepository _ProductRepository = new ProductRepository(); 
  
  IQueryable&lt;Product&gt; products = _ProductRepository.GetAllProducts();
  </code></pre>
  
  <p>If I would like to filter <code>IQueryable&lt;Product&gt; products</code>, for instance by taking those product with <strong>price > 100</strong> or just those with <strong>color = "yellow"</strong>. </p>
  
  <p>So I was wondering, instead of creating methods in <code>ProductRepository</code> such as:</p>
  
  <pre><code>IQueryable&lt;Product&gt; GetAllProductsByColor(int colorId)
  </code></pre>
  
  <p>I was wondering if it is a good practice to create in my <strong>Service Layer</strong> a set of methods that accept <code>IQueryable&lt;Product&gt;</code> as parameter and perform the filtering directly there:</p>
  
  <pre><code>IQueryable&lt;Product&gt; FilterProducts(IQueryable&lt;Product&gt; products, Dictionary&lt;string, object&gt; filters)
  </code></pre>
  
  <p>Where <code>Dictionary&lt;string, string&gt;</code> represent a set with <strong>(propertyName, value)</strong>.</p>
  
  <p>The advantage of this solution is that if I have to apply multiple filters I just pass the <code>IQueryable&lt;Product&gt;</code> already filtered, instead of taking everytime the intersection between the filtered product sets. </p>
  
  <p>Is it a good practice (as long as I keep the <strong>context open</strong>) or it is not "allowed"by the multi-layered architecure pattern?</p>