本网站目前按照数据内容主要划分为全球矿业资讯、矿业信息、专题产品、线下资源几个板块;按照区域分工和业务分工,建立了6个区域研究专题和部分应用专题。用户可以一直站了解全球矿业活动态势、最新矿业资讯动态、矿产资源分布,获取地质矿产及物化遥水工环数据资料,并可联系相关单位寻求定制化数据加工服务、综合研究服务和咨询服务等。

 您当前的位置:首页 > > 勘探开发

矿业资讯测试001
[发布时间:2021-03-10 浏览次数:735]

.NetCore 扩展封装 Expression<Func<T, bool>> 查询条件遇到的问题


前面的文章封装了查询条件 自己去组装条件,但是对 And  Or  这种组合支持很差,但是也不是不能支持,只是要写更多的代码看起来很臃肿

根据 Where(Expression<Func<T, bool>>) 我们直接来处理这个,在处理这个之前其实看了下

Expression这个对象的处理,本生里面是包含了 AndAlso 、 Or 的处理   先来看看这个会遇到什么问题?为什么不行?

比如:

Expression.AndAlso(first,second)

来一段之前的扩展

 public static Expression AndExpression(this Expression expression, Expression right)
        { return Expression.AndAlso(expression, right);
           
        }
public static Expression OrExpression(this Expression expression, Expression right)
        { return Expression.Or(expression, right);
           
        }
public static Expression<Func<T,bool>> ToFilter<T>(this Expression expression)
        { return Expression.Lambda<Func<T, bool>>(expression, Expression.Parameter(typeof(T)));
          
        }

 

本质上没什么不同,最后连接都能拿到相关的表达式

复制代码
Expression filter= Expression.Constant(true, typeof(bool)); if (!string.IsNullOrEmpty(username))
            {
                filter = filter.AndExpression(new UosoConditions {
                    Key = "UserName",
                    Operator = UosoOperatorEnum.Contains,
                    Value = username,
                    ValueType = "string" }.Parser<IdentityUser>());
            }
复制代码

按照如上写法多写几个条件,2个查询条件,2个值,感觉没问题, 但是运行到Where的时候报错误 表到时Parameter参数的个数对应不上表达式参数的个数,参数丢失了?

参数的值跟随表达式,在组合的时候需要重新组合参数,如果直接组合表达式,参数不会发生变化所以需要处理下参数问题,对(Expression<Func<T, bool>>) 的扩展就迎刃而解了

正确的处理方式:

复制代码
   public static class ExpressionExtensions
    { /// <summary> /// 添加And条件 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="first"></param> /// <param name="second"></param> /// <returns></returns> public static Expression<Func<T, bool>> And<T>( this Expression<Func<T, bool>> first,
        Expression<Func<T, bool>> second)
        { return first.AndAlso<T>(second, Expression.AndAlso);
        } /// <summary> /// 添加Or条件 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="first"></param> /// <param name="second"></param> /// <returns></returns> public static Expression<Func<T, bool>> Or<T>( this Expression<Func<T, bool>> first,
            Expression<Func<T, bool>> second)
        { return first.AndAlso<T>(second, Expression.OrElse);
        } /// <summary> /// 合并表达式以及参数 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="expr1"></param> /// <param name="expr2"></param> /// <param name="func"></param> /// <returns></returns> private static Expression<Func<T, bool>> AndAlso<T>( this Expression<Func<T, bool>> expr1,
        Expression<Func<T, bool>> expr2,
        Func<Expression, Expression, BinaryExpression> func)
        { var parameter = Expression.Parameter(typeof(T)); var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter); var left = leftVisitor.Visit(expr1.Body); var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter); var right = rightVisitor.Visit(expr2.Body); return Expression.Lambda<Func<T, bool>>(
                func(left, right), parameter);



        } private class ReplaceExpressionVisitor
 : ExpressionVisitor
        { private readonly Expression _oldValue; private readonly Expression _newValue; public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
            {
                _oldValue = oldValue;
                _newValue = newValue;
            } public override Expression Visit(Expression node)
            { if (node == _oldValue) return _newValue; return base.Visit(node);
            }
        }

【版权声明】全球地质矿产信息网欢迎各方媒体、网站、机构或个人转载、引用我们网站原创内容,但请注明信息来源为全球地质矿产信息网(http://ggmd2.ngac.cn/);同时,我们倡导尊重与保护知识产权,如擅自篡改稿件来源,自负版权等法律责任。如对稿件内容有疑议,请及时与本网站联系(412074237@qq.com,010-58584231)。

标签:测试测色

相关新闻更多》