繁体   English   中英

如何在 linq Query 中传递表达式列表

[英]How to pass List of Expression in linq Query

我想使用通用搜索参数制作用于分页的通用类。 我使用反射来获取过滤器属性。 可以使用我不太了解的表达式来实现。 任何帮助 wud 不胜感激。

public IEnumerable<T> ModelPagination(F filters) <-- F class filter properties eg. Name, CNIC for search
        {
            Type C = Type.GetType("filters");
            PropertyInfo[] properties = C.GetProperties();

            foreach (PropertyInfo prop in properties)
            {
                 prop.Name;
            }

            return dbEntity.Where(x => ...... ).ToList(); <--- want to pass each property as lambda for something like x -> x.Name == filters.Name || filters.Name == Null 

        }

这将构建 lambda 表达式,它将与泛型类型TFilter类之间的属性相交并比较它们的相等性,并且每个单独的属性对都与 AND 条件相结合。

public static IEnumerable<T> ModelPagination<T>(F filter) 
{
        // all properties which are in the fiter class also present in the generic type T
        var commonPropertyNames = filter
                .GetType()
                .GetProperties(BindingFlags.Instance | BindingFlags.Public)
                .Select(x => x.Name)
                .Intersect(
                    typeof(T)
                    .GetProperties(BindingFlags.Instance | BindingFlags.Public)
                    .Select(x => x.Name)
                );
        var argumentExpression = Expression.Parameter(typeof(T), "x");
        var filterConstantExpression = Expression.Constant(filter);

        // build the expression
        var expression = (BinaryExpression)null;
        foreach (var propertyName in commonPropertyNames)
        {
            var filterPropertyExpression = Expression.Property(filterConstantExpression, propertyName);

            var equalExpression = Expression.Equal(
                Expression.Property(argumentExpression, propertyName),
                filterPropertyExpression
            );

            var nullCheckExpression = Expression.Equal(
                filterPropertyExpression,
                Expression.Constant(null)
            );

            var orExpression = Expression.OrElse(equalExpression, nullCheckExpression);

            if (expression == null)
            {
                expression = orExpression;
            }
            else
            {
                expression = Expression.AndAlso(expression, orExpression);
            }
        }

        var lambda = Expression.Lambda<Func<T, bool>>(expression, argumentExpression);

        return dbContext.Entry<T>().Where(lambda).ToList();
    }

如果你有像这样的T类型{ FirstName, LastName }和像这样{ FirstName } Filter类,它将创建以下表达式

x => x.FirstName == filter.FirstName || filter.FirstName == null

如果你有像这样的T类型{ FirstName, LastName }和像这样的Filter class { FirstName, LastName }它将创建以下表达式

x => (x.FirstName == filter.FirstName || filter.FirstName == null) 
     && (x.LastName == filter.LastName || filter.LastName == null)

这将完成这项工作,但仍有优化空间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM