替代多个IF / CASE语句 [英] Alternative for multiple IF/CASE statements
问题描述
有没有一种方法,以避免在C#中的多个IF / CASE语句?
在我的应用我将最终用于创建LINQ查询,其中8+领域每一个表情可以为空或!=空,因此它会给我64的方案。
我不提供任何代码样本,因为我可以用IF / CASE和做将其简化为尽我所能。
如果你熟悉一些有用的方法对这个问题,我将不胜感激任何建议。
代码示例(只包括两个代表,但我不得不添加更多的过滤数据)
库
公共虚拟IEnumerable的< T>获取(表达式来; Func键< T,BOOL>>过滤器= null,则表达式来; Func键< T,BOOL>>过滤器1 = NULL)
{
的IQueryable< T>查询= dbSet;
如果(过滤器!= NULL)
{
=查询query.Where(过滤器);
返回query.ToList();
}
如果(过滤器1!= NULL)
{
=查询query.Where(滤波器1);
返回query.ToList();
}
,否则
{
返回query.ToList();
}
}
控制器
公众的ActionResult指数(字符串searchFullName,串searchExtension)
{
变种extensionList =新的List<串>() ;
变种从扩展中的n unitofwork.DomainRepository.Get()
选择n.Extension =;
extensionList.AddRange(extensions.Distinct());
ViewBag.searchExtension =新的SelectList(extensionList);
如果(String.IsNullOrEmpty(searchFullName)及!&安培;!String.IsNullOrEmpty(searchExtension))
{
返回查看(unitofwork.DomainRepository.Get(N => n.Extension == searchExtension&放大器;&放大器; n.Name.Contains(searchFullName)));
}
,否则如果
{
返回查看(String.IsNullOrEmpty(searchExtension)!)(unitofwork.DomainRepository.Get(N => n.Extension == searchExtension)) ;
}
,否则如果(String.IsNullOrEmpty(searchFullName)及和放大器; String.IsNullOrEmpty(searchExtension))
{
返回查看(unitofwork.DomainRepository.Get());
}
,否则如果(String.IsNullOrEmpty(searchFullName)及!&安培; String.IsNullOrEmpty(searchExtension))
{
返回查看(unitofwork.DomainRepository.Get(N = > n.Name.Contains(searchFullName)));
}
,否则
{
返回查看(unitofwork.DomainRepository.Get());
}
}
是的这是可能的,使用LINQ的强大总结
方法(一版的倍,从函数式编程
功能)。
公共虚拟IEnumerable的< T> FilterOnAll(PARAMS表达式来;谓语< T>过滤器)
{
返回filters.Aggregate(dbSet,(ACC,元素)=> acc.Where(元素));
}
公共虚拟IEnumerable的< T> FilterOnAny(PARAMS表达式来;谓语< T>过滤器)
{
表达式来;谓语< T>> alwaysTrue = _ =>真正;
VAR compositeFilter = filters.Aggregate(alwaysTrue,(ACC,元素)=> acc.Or(元素));
返回dbSet.Where(compositeFilter);
}
您可以然后撰写这两个建设者创造几乎任何你想要的逻辑条件从你的控制器中。
祝你好运。
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());
}
}
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.
这篇关于替代多个IF / CASE语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!