Alternative for multiple IF/CASE statements

淺唱寂寞╮ 提交于 2019-12-23 05:15:54

问题


Is there a way to avoid multiple IF/CASE statements in C#?

In my app I will end up with 8+ fields used to create a Linq query where every expression can be null or != null so it will give me 64 scenarios.

I'm not providing any code samples because I can do it using IF/CASE and simplify it as much as I can.

If You are familiar with some useful approaches to that problem I will appreciate any advice.

Code Sample (it only includes two delegates but I'll have to add more to filter data)

Repository

    public virtual IEnumerable<T> Get(Expression<Func<T, bool>> filter = null, Expression<Func<T, bool>> filter1 = null)
            {
                IQueryable<T> query = dbSet;

                if (filter != null)
                {
                    query = query.Where(filter);
                    return query.ToList();
                }

                if (filter1 != null)
                {
                    query = query.Where(filter1);
                    return query.ToList();
                }
                else
               {
                    return query.ToList();
               }
            }

Controller

public ActionResult Index(string searchFullName, string searchExtension)
    {
        var extensionList = new List<string>();
        var extensions = from n in unitofwork.DomainRepository.Get()
                         select n.Extension;
        extensionList.AddRange(extensions.Distinct());
        ViewBag.searchExtension = new SelectList(extensionList);
        if (!String.IsNullOrEmpty(searchFullName) && !String.IsNullOrEmpty(searchExtension))
        {
            return View(unitofwork.DomainRepository.Get(n => n.Extension == searchExtension && n.Name.Contains(searchFullName)));
        }
        else if (!String.IsNullOrEmpty(searchExtension))
        {
            return View(unitofwork.DomainRepository.Get(n => n.Extension == searchExtension));
        }
        else if (String.IsNullOrEmpty(searchFullName) && String.IsNullOrEmpty(searchExtension))
        {
            return View(unitofwork.DomainRepository.Get());
        }
        else if (!String.IsNullOrEmpty(searchFullName) && String.IsNullOrEmpty(searchExtension))
        {
            return View(unitofwork.DomainRepository.Get(n => n.Name.Contains(searchFullName)));
        }
        else
        {
            return View(unitofwork.DomainRepository.Get());
        }
    }

回答1:


Yes it is possible, using Linq's powerful Aggregate method (a version of the fold function from functional programming).

public virtual IEnumerable<T> FilterOnAll(params Expression<Predicate<T> filters)
{
    return filters.Aggregate(dbSet, (acc, element) => acc.Where(element));
}

public virtual IEnumerable<T> FilterOnAny(params Expression<Predicate<T> filters)
{
    Expression<Predicate<T>> alwaysTrue = _ => true;
    var compositeFilter = filters.Aggregate(alwaysTrue, (acc, element) => acc.Or(element));
    return dbSet.Where(compositeFilter);
}

You can then compose these two builders to create pretty much any logical condition you want from within your controller.

Good luck.




回答2:


What you can do is an or statement in your where clause

where (variable1 == null || b.data = variable1) and just do that for all 8 if im understanding your problem if its null it passes over it as true else it checks against the data.




回答3:


Your entire if .. elseif .. else block can be replaced by:

return View(unitofwork.DomainRepository.Get(n => 
     (string.IsNullOrEmpty(searchFullName)  || n.Name.Contains(searchFullName))
  && (string.IsNullOrEmpty(searchExtension) || n.Extension == searchExtension)));


来源:https://stackoverflow.com/questions/19730673/alternative-for-multiple-if-case-statements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!