3

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

4

1 回答 1

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

开关仍然存在,但不会重复。

于 2012-07-30T22:49:13.110 回答