거의 200 개의 케이스를 테스트하는 술어 핸들러가 있으며 각 테스트에는 5 가지 가능한 비교가 포함됩니다. 이 코드를 간소화하고 싶지만이 구문을 표현하는 방법과 함께 벽을 치고 있습니다.반복 비교를위한 술어 표현식 기능
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 번 반복되며 각 경우마다 유일한 차이점은 검사 할 필드 이름입니다. 가능한 한이 코드를 줄이려고합니다.
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");
}
}
스위치가 여전히 있지만, 그들은 반복하지 않을 :
나는 'value'에 대한 센티널로서 -1을 사용하지 않기를 바란다. TryParse는 무엇을 상관없이 값을 설정할 수있다. false를 반환하면'value'를 0으로 설정합니다. 즉,'f.TextValue'가 -1로 해석 될 때만'value'는 -1과 같습니다. 그리고 왜 TryParse의 반환 값을 확인하지 않습니까? – phoog