用于重复比较的谓词表达函数

时间:2012-07-30 22:34:00

标签: c# expression predicatebuilder

我有一个谓词处理程序,可以测试近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次,每种情况下唯一不同的是要检查的字段名称。我想尽可能地减少这段代码。

1 个答案:

答案 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");
    }
}

开关仍在那里,但它们不会重复。