通用类的谓词builder

发布于 2025-01-26 00:15:42 字数 1811 浏览 4 评论 0原文

我正在尝试创建一种方法,其中我将通过包含字段,比较和价值的过滤器列表。这是我现在的参数

public class QueryFilter
{
    public string Field { get; set; }
    public object Value { get; set; }   
    public string Comparer { get; set; }
}

,我创建了一种方法,该方法将根据传递的QueryFilter列表返回表达式。

public Expression<Func<TEntity, bool>> QueryFilterBuilder<TEntity>(List<QueryFilter> filters)
    {
        try
        {
            var predicate = PredicateBuilder.New<TEntity>(true);

            filters.ForEach(filter =>
            {
                switch (filter.Comparer.ToLower())
                {
                    case QueryFilterComparer.Eq: // equals
                        predicate = predicate.And(x => filter.Field == filter.value); // something like this
                        break;
                    case QueryFilterComparer.Ne: // not equal
                        // Add not equal filter logic here
                        break;
                    case QueryFilterComparer.Any: // any
                        break;
                    case QueryFilterComparer.Gt: // greater than
                        break;
                    case QueryFilterComparer.Gte: // greater than equal
                        break;
                    case QueryFilterComparer.Lt: // less than
                        break;
                    case QueryFilterComparer.Lte: // less than equal
                        break;
                    case QueryFilterComparer.Contains: // contains
                        break;
                    default:
                        break;
                };
            });

            return predicate;
        }
        catch (Exception)
        {
            throw;
        }
    }

问题是我不确定如何使用通用类实现此目标。可以这样做吗?

I am trying to create a method where I'll pass a list of filters containing the field,comparer and value. Here is my parameter

public class QueryFilter
{
    public string Field { get; set; }
    public object Value { get; set; }   
    public string Comparer { get; set; }
}

Now, I created a method that will return an expression based on the list of QueryFilter that was passed.

public Expression<Func<TEntity, bool>> QueryFilterBuilder<TEntity>(List<QueryFilter> filters)
    {
        try
        {
            var predicate = PredicateBuilder.New<TEntity>(true);

            filters.ForEach(filter =>
            {
                switch (filter.Comparer.ToLower())
                {
                    case QueryFilterComparer.Eq: // equals
                        predicate = predicate.And(x => filter.Field == filter.value); // something like this
                        break;
                    case QueryFilterComparer.Ne: // not equal
                        // Add not equal filter logic here
                        break;
                    case QueryFilterComparer.Any: // any
                        break;
                    case QueryFilterComparer.Gt: // greater than
                        break;
                    case QueryFilterComparer.Gte: // greater than equal
                        break;
                    case QueryFilterComparer.Lt: // less than
                        break;
                    case QueryFilterComparer.Lte: // less than equal
                        break;
                    case QueryFilterComparer.Contains: // contains
                        break;
                    default:
                        break;
                };
            });

            return predicate;
        }
        catch (Exception)
        {
            throw;
        }
    }

The problem is I'm not sure how to implement this with generic class. Is it possible to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雄赳赳气昂昂 2025-02-02 00:15:42

您可以使用Expression API这样实现此信息:

public static Expression<Func<TEntity, bool>> QueryFilterBuilder<TEntity> 
(List<QueryFilter> filters)
{
    Expression GetExpressionForQueryFilter(QueryFilter filter, Expression param)
        => filter.Comparer switch
        {
            QueryFilterComparer.Eq => Expression.Equal(GetField(filter.Field, param), Expression.Constant(filter.Value)),
            QueryFilterComparer.Ne => Expression.Not(Expression.Equal(GetField(filter.Field, param), Expression.Constant(filter.Value))),
            QueryFilterComparer.Any => throw new NotImplementedException(),
            QueryFilterComparer.Gt => throw new NotImplementedException(),
            QueryFilterComparer.Gte => throw new NotImplementedException(),
            QueryFilterComparer.Lt => throw new NotImplementedException(),
            QueryFilterComparer.Lte => throw new NotImplementedException(),
            QueryFilterComparer.Contains => throw new NotImplementedException(),
            _ => throw new ArgumentOutOfRangeException()
    };

    Expression GetField(string field, Expression param)
    => Expression.Field(param, typeof(TEntity).GetField(field) ?? throw new ArgumentOutOfRangeException());

    var parameter = Expression.Parameter(typeof(TEntity), "parameter");

    return Expression.Lambda<Func<TEntity, bool>>(filters.Aggregate(
        (Expression) Expression.Constant(true),
        (acc, next) => Expression.MakeBinary(ExpressionType.AndAlso, acc, GetExpressionForQueryFilter(next, parameter))),
    parameter);
}

You can implement this using Expression api like so:

public static Expression<Func<TEntity, bool>> QueryFilterBuilder<TEntity> 
(List<QueryFilter> filters)
{
    Expression GetExpressionForQueryFilter(QueryFilter filter, Expression param)
        => filter.Comparer switch
        {
            QueryFilterComparer.Eq => Expression.Equal(GetField(filter.Field, param), Expression.Constant(filter.Value)),
            QueryFilterComparer.Ne => Expression.Not(Expression.Equal(GetField(filter.Field, param), Expression.Constant(filter.Value))),
            QueryFilterComparer.Any => throw new NotImplementedException(),
            QueryFilterComparer.Gt => throw new NotImplementedException(),
            QueryFilterComparer.Gte => throw new NotImplementedException(),
            QueryFilterComparer.Lt => throw new NotImplementedException(),
            QueryFilterComparer.Lte => throw new NotImplementedException(),
            QueryFilterComparer.Contains => throw new NotImplementedException(),
            _ => throw new ArgumentOutOfRangeException()
    };

    Expression GetField(string field, Expression param)
    => Expression.Field(param, typeof(TEntity).GetField(field) ?? throw new ArgumentOutOfRangeException());

    var parameter = Expression.Parameter(typeof(TEntity), "parameter");

    return Expression.Lambda<Func<TEntity, bool>>(filters.Aggregate(
        (Expression) Expression.Constant(true),
        (acc, next) => Expression.MakeBinary(ExpressionType.AndAlso, acc, GetExpressionForQueryFilter(next, parameter))),
    parameter);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文