Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><em>Disclaimer: I'm fairly new to this and there is probably much better ways to do this. Any feedback is higlhy appreciated.</em></p> <p>Note that this method has no error/null checking. Since it uses reflection, you should profile it if you plan to use it in production.</p> <pre><code>public static IEnumerable&lt;T&gt; Filter&lt;T&gt;(IEnumerable&lt;T&gt; collection, Dictionary&lt;string, object&gt; filters) { var type = typeof (T); var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); var queryable = collection.AsQueryable(); var instance = Expression.Parameter(type, "instance"); var expressions = new Stack&lt;Expression&gt;(); foreach (var filter in filters) { var propertyName = filter.Key; var property = properties.FirstOrDefault(x =&gt; x.Name == propertyName); if (property == null) continue; var left = Expression.Property(instance, property); var right = Expression.Constant(filter.Value, property.PropertyType); var expr = Expression.Equal(left, right); expressions.Push(expr); } Expression call = null; Expression previousExpression = null; while(expressions.Count &gt; 0) { var expr = expressions.Pop(); if(previousExpression == null) { previousExpression = expr; call = expr; } else { var and = Expression.AndAlso(previousExpression, expr); call = and; previousExpression = and; } } var whereCallExpression = Expression.Call( typeof(Queryable), "Where", new[] { queryable.ElementType }, queryable.Expression, Expression.Lambda&lt;Func&lt;T, bool&gt;&gt;(call, new[] { instance })); return queryable.Provider.CreateQuery&lt;T&gt;(whereCallExpression); } </code></pre> <p>It overates all filters and tries to find a matching property. If it does find a property, it creates a EqualExpression which compares the actual value and the value you want to filter by. It then creates a <code>MethodCallExpression</code> which is passed to the query provider.</p> <p>Theese expressions are then combined. I think the part with the stack is wrong, and that there is a better way to do it.</p> <p>Usage:</p> <pre><code>var persons = new List&lt;Person&gt; {new Person {Name = "Alex", Age = 22}, new Person {Name = "Jesper", Age = 30}}; var filters = new Dictionary&lt;string, object&gt;(); filters.Add("Name", "Alexander Nyquist"); var results = Filter(persons, filters); </code></pre> <p>Since it's building expressions, it does works with Linq 2 Sql (tested) and probably Entity Framework. Linq 2 sql produces the following query:</p> <pre><code>SELECT [t0].[Id], [t0].[Name], [t0].[Email] FROM [dbo].[Persons] AS [t0] WHERE [t0].[Name] = @p0 -- @p0: Input VarChar (Size = 8000; Prec = 0; Scale = 0) [Alexander Nyquist] -- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1 </code></pre> <p>Hope this helps.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload