How to filter IEnumerable based on an entity input parameter

前端 未结 3 1174
后悔当初
后悔当初 2021-01-01 01:31

I\'m using now Entity framework- but it\'s a problem \"shared\" between all ORM\'s and even IEnumerable.

Let\'s say I have a method in MVC looks like this:



        
相关标签:
3条回答
  • 2021-01-01 01:53

    Try that. This is using reflection and expressions to build the query dynamically. I tested it only with objects.

    static IQueryable<T> Filter<T>(IQueryable<T> col, T filter)
    {
        foreach (var pi in typeof(T).GetProperties())
        {
            if (pi.GetValue(filter) != null)
            {
                var param = Expression.Parameter(typeof(T), "t");
                var body = Expression.Equal(
                    Expression.PropertyOrField(param, pi.Name),
                    Expression.PropertyOrField(Expression.Constant(filter), pi.Name));
                var lambda = Expression.Lambda<Func<T, bool>>(body, param);
                col = col.Where(lambda);
            }
        }
    
        return col;
    }
    
    0 讨论(0)
  • 2021-01-01 01:56

    Your hard coded method is the best method generally.

    However you can try to make your life a little easier by writing an appropriate extension method to help keep the code clean.

    Try this for example:

    public static class QueryableEx
    {
        public static IQueryable<T> Where<T>(
            this IQueryable<T> @this,
            bool condition,
            Expression<Func<T, bool>> @where)
        {
            return condition ? @this.Where(@where) : @this;
        }
    }
    

    Now you could write this code:

    [HttpPost]
    public ActionResult Foo(FooModel model)
    {
        using (var context = new Context())
        {
            var data = context.Foo
                .Where(model.Date != null, x => x.Date == model.Date)
                .Where(model.Name != null, x => x.Name == model.Name)
                .Where(model.ItemCode != null, x => x.ItemCode == model.ItemCode)
                .ToList();
            return View(data);
        }
    }
    

    (Please don't forget to dispose of your context or use using to do it for you.)

    0 讨论(0)
  • 2021-01-01 02:07

    I think you should encapsulate your logic into your Foo entity, e.g.

       public Foo
       {
         public bool isMatch(Model model)
         {
           // check your rules and return result
         }
       }
    

    and use it in linq. Or look at Specification pattern

    0 讨论(0)
提交回复
热议问题