我有一个谓词处理程序,可以测试近200个案例,每个测试涉及五个可能的比较。我想简化这段代码,但是如何在语法上表达这个代码。
public static Expression<Func<OADataConsolidated, bool>> Match(DOTSearchFilter filters)
{
var predicate = (filters.OrFilters.Count > 0) ? PredicateBuilder.False<OADataConsolidated>() : PredicateBuilder.True<OADataConsolidated>();
foreach (DOTFilter f in filters.AndFilters)
{
int value = -1;
int.TryParse(f.TextValue, out value);
switch (f.Type)
{
case DOTFilter.FilterType.SCO:
switch (f.IdValue)
{
case 4: // GED: Reasoning
switch (f.Comp)
{
case DOTFilter.Comparitor.LessThan:
predicate = predicate.And(p => p.ajblGEDR_Mean < value);
break;
case DOTFilter.Comparitor.EqualOrLess:
predicate = predicate.And(p => p.ajblGEDR_Mean <= value);
break;
case DOTFilter.Comparitor.EqualTo:
predicate = predicate.And(p => p.ajblGEDR_Mean == value);
break;
case DOTFilter.Comparitor.EqualOrGreater:
predicate = predicate.And(p => p.ajblGEDR_Mean >= value);
break;
case DOTFilter.Comparitor.GreaterThan:
predicate = predicate.And(p => p.ajblGEDR_Mean > value);
break;
}
break;
case 5: // GED: Mathematics
switch (f.Comp)
{
case DOTFilter.Comparitor.LessThan:
predicate = predicate.And(p => p.ajblGEDM < value);
break;
case DOTFilter.Comparitor.EqualOrLess:
predicate = predicate.And(p => p.ajblGEDM <= value);
break;
case DOTFilter.Comparitor.EqualTo:
predicate = predicate.And(p => p.ajblGEDM == value);
break;
case DOTFilter.Comparitor.EqualOrGreater:
predicate = predicate.And(p => p.ajblGEDM >= value);
break;
case DOTFilter.Comparitor.GreaterThan:
predicate = predicate.And(p => p.ajblGEDM > value);
break;
}
break;
上面的switch语句重复了近200次,每种情况下唯一不同的是要检查的字段名称。我想尽可能地减少这段代码。
答案 0 :(得分:2)
您可以像这样动态构建表达式:
string propertyName = GetPropertyName(f);
ExpressionType comp = GetComparisonType(f);
ParameterExpression p = Expression.Parameter(typeof(OADataConsolidated));
Expression<Func<OADataConsolidated, bool>> expr =
Expression.Lambda<Func<OADataConsolidated, bool>>(
Expression.MakeBinary(
comp,
Expression.Property(p, propertyName),
Expression.Constant((double)value)),
p);
predicate = predicate.And(expr);
...
static string GetPropertyName(DOTFilter filter)
{
switch(filter.IdValue)
{
case 4: // GED: Reasoning
propertyName = "ajblGEDR_Mean";
break;
case 5: // GED: Mathematics
propertyName = "ajblGEDM";
break;
...
default:
throw new ArgumentException("Unknown Id value");
}
}
static ExpressionType GetComparisonType(DOTFilter filter)
{
switch (filter.Comp)
{
case DOTFilter.Comparitor.LessThan:
return ExpressionType.LessThan;
case DOTFilter.Comparitor.EqualOrLess:
return ExpressionType.LessThanOrEqual;
case DOTFilter.Comparitor.EqualTo:
return ExpressionType.Equal;
case DOTFilter.Comparitor.EqualOrGreater:
return ExpressionType.GreaterThanOrEqual;
case DOTFilter.Comparitor.GreaterThan:
return ExpressionType.GreaterThan;
default:
throw new ArgumentException("Unknown Comp value");
}
}
开关仍在那里,但它们不会重复。