liukuo362573 / YiShaAdmin

基于 .NET Core MVC 的权限管理系统,代码易读易懂、界面简洁美观
MIT License
2.42k stars 872 forks source link

表达式查询增加字段自动过滤 #159

Closed jhzou1 closed 1 year ago

jhzou1 commented 1 year ago

public static Expression<Func<T, bool>> GetExpressionItems<T, TT>(TT input) { var parameter = Expression.Parameter(typeof(T), "entity"); Expression expression = Expression.Constant(true);

        var properties = typeof(TT).GetProperties();

        var targetProperties = typeof(T).GetProperties();

        foreach (var property in properties)
        {
            //字符类型筛选
            if (property.PropertyType == typeof(string))
            {

                var value = property.GetValue(input);

                if (value != null && !string.IsNullOrEmpty(value.ToString()))
                {
                    var propertyExpression = Expression.Property(parameter, property.Name);
                    var valueExpression = Expression.Constant(value);
                    var containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
                    var containsExpression = Expression.Call(propertyExpression, containsMethod, valueExpression);
                    expression = Expression.AndAlso(expression, containsExpression);
                }
            }
            //日期类型筛选
            else if (property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime?))
            {
                var value = property.GetValue(input);

                if (value != null)
                {
                    // 开始日期筛选
                    if (property.Name.Contains("Start"))
                    {
                        var realPropertyName = property.Name.Substring(0, property.Name.Length - "Start".Length);
                        var propertyExpression = Expression.Property(parameter, realPropertyName);
                        var entityfield = targetProperties.FirstOrDefault(s => s.Name == realPropertyName);
                        var startDateTime = (DateTime)value;

                        if (entityfield.PropertyType == typeof(DateTime?))
                        {
                            var greaterThanOrEqualExpression = Expression.GreaterThanOrEqual(propertyExpression, Expression.Constant(startDateTime, typeof(DateTime?)));
                            expression = Expression.AndAlso(expression, greaterThanOrEqualExpression);
                        }
                        else
                        {
                            var greaterThanOrEqualExpression = Expression.GreaterThanOrEqual(propertyExpression, Expression.Constant(startDateTime));
                            expression = Expression.AndAlso(expression, greaterThanOrEqualExpression);
                        }

                    }
                    // 结束日期筛选
                    else if (property.Name.Contains("End"))
                    {
                        var realPropertyName = property.Name.Substring(0, property.Name.Length - "End".Length);
                        var propertyExpression = Expression.Property(parameter, realPropertyName);
                        var entityfield = targetProperties.FirstOrDefault(s => s.Name == realPropertyName);
                        var endDateTime = ((DateTime)value).Date.AddDays(1).AddTicks(-1);

                        if (entityfield.PropertyType == typeof(DateTime?))
                        {
                            var lessThanOrEqualExpression = Expression.LessThanOrEqual(propertyExpression, Expression.Constant(endDateTime, typeof(DateTime?)));
                            expression = Expression.AndAlso(expression, lessThanOrEqualExpression);
                        }
                        else
                        {
                            var lessThanOrEqualExpression = Expression.LessThanOrEqual(propertyExpression, Expression.Constant(endDateTime));
                            expression = Expression.AndAlso(expression, lessThanOrEqualExpression);
                        }

                    }
                    // 其他日期属性
                    else
                    {
                        var propertyExpression = Expression.Property(parameter, property.Name);
                        var equalExpression = Expression.Equal(propertyExpression, Expression.Constant(value));
                        expression = Expression.AndAlso(expression, equalExpression);
                    }
                }

            }
            //数值类型
            else if (property.PropertyType == typeof(int?) || property.PropertyType == typeof(int))
            {
                var value = property.GetValue(input);
                var propertyExpression = Expression.Property(parameter, property.Name);
                var entityfield = targetProperties.FirstOrDefault(s => s.Name == property.Name);

                if (value != null)
                {
                    if (entityfield.PropertyType == typeof(int?))
                    {
                        var equalExpression = Expression.Equal(propertyExpression, Expression.Constant(value, typeof(int?)));
                        expression = Expression.AndAlso(expression, equalExpression);
                    }
                    else
                    {
                        var equalExpression = Expression.Equal(propertyExpression, Expression.Constant(value));
                        expression = Expression.AndAlso(expression, equalExpression);
                    }

                }

            }
            //float
            else if (property.PropertyType == typeof(float?) || property.PropertyType == typeof(float))
            {
                var value = property.GetValue(input);
                var propertyExpression = Expression.Property(parameter, property.Name);
                var entityfield = targetProperties.FirstOrDefault(s => s.Name == property.Name);

                if (value != null)
                {
                    if (entityfield.PropertyType == typeof(float?))
                    {
                        var equalExpression = Expression.Equal(propertyExpression, Expression.Constant(value, typeof(float?)));
                        expression = Expression.AndAlso(expression, equalExpression);
                    }
                    else
                    {
                        var equalExpression = Expression.Equal(propertyExpression, Expression.Constant(value));
                        expression = Expression.AndAlso(expression, equalExpression);
                    }

                }

            }

        }

        return Expression.Lambda<Func<T, bool>>(expression, parameter);
    }