zoukankan      html  css  js  c++  java
  • Linq动态条件

    很多情况下,我们开发程序,需要动态拼接SQL查询语句;

    比如  select top 1 * from User where age= 18  and  name = 'renruiquan'

    其中红色的代码,是我们需要根据查询条件是否为空,来判,要不要加在查询的SQL里;

    换成Linq里就不能这么直接的去拼接了,好在国外的大神有给我们解决方案。下面直接上代码:

    新手同学不需要关心代码具体是怎么实现的,只需要知道怎么调用就好。当然,你能研究一下,给自己充电,也是再好不过了

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Reflection;
    using System.Text;
    using System.Threading.Tasks;
    
    
    namespace JQ.GameClient.Common
    {
        /// <summary>
        /// Enables the efficient, dynamic composition of query predicates.
        /// </summary>
        public static class PredicateBuilder
        {
            /// <summary>
            /// Creates a predicate that evaluates to true.
            /// </summary>
            public static Expression<Func<T, bool>> True<T>() { return param => true; }
    
            /// <summary>
            /// Creates a predicate that evaluates to false.
            /// </summary>
            public static Expression<Func<T, bool>> False<T>() { return param => false; }
    
            /// <summary>
            /// Creates a predicate expression from the specified lambda expression.
            /// </summary>
            public static Expression<Func<T, bool>> Create<T>(Expression<Func<T, bool>> predicate) { return predicate; }
    
            /// <summary>
            /// Combines the first predicate with the second using the logical "and".
            /// </summary>
            public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
            {
                return first.Compose(second, Expression.AndAlso);
            }
    
            /// <summary>
            /// Combines the first predicate with the second using the logical "or".
            /// </summary>
            public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
            {
                return first.Compose(second, Expression.OrElse);
            }
    
            /// <summary>
            /// Negates the predicate.
            /// </summary>
            public static Expression<Func<T, bool>> Not<T>(this Expression<Func<T, bool>> expression)
            {
                var negated = Expression.Not(expression.Body);
                return Expression.Lambda<Func<T, bool>>(negated, expression.Parameters);
            }
    
            /// <summary>
            /// Combines the first expression with the second using the specified merge function.
            /// </summary>
            static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
            {
                // zip parameters (map from parameters of second to parameters of first)
                var map = first.Parameters
                    .Select((f, i) => new { f, s = second.Parameters[i] })
                    .ToDictionary(p => p.s, p => p.f);
    
                // replace parameters in the second lambda expression with the parameters in the first
                var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
    
                // create a merged lambda expression with parameters from the first expression
                return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
            }
    
            /// <summary>
            /// ParameterRebinder
            /// </summary>
            class ParameterRebinder : ExpressionVisitor
            {
                /// <summary>
                /// The ParameterExpression map
                /// </summary>
                readonly Dictionary<ParameterExpression, ParameterExpression> map;
    
                /// <summary>
                /// Initializes a new instance of the <see cref="ParameterRebinder"/> class.
                /// </summary>
                /// <param name="map">The map.</param>
                ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
                {
                    this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
                }
    
                /// <summary>
                /// Replaces the parameters.
                /// </summary>
                /// <param name="map">The map.</param>
                /// <param name="exp">The exp.</param>
                /// <returns>Expression</returns>
                public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
                {
                    return new ParameterRebinder(map).Visit(exp);
                }
    
                /// <summary>
                /// Visits the parameter.
                /// </summary>
                /// <param name="p">The p.</param>
                /// <returns>Expression</returns>
                protected override Expression VisitParameter(ParameterExpression p)
                {
                    ParameterExpression replacement;
    
                    if (map.TryGetValue(p, out replacement))
                    {
                        p = replacement;
                    }
    
                    return base.VisitParameter(p);
                }
            }
        }
    
    }

    代码调用:

                //动态构造查询条件
                var predicate = PredicateBuilder.True<UserInfo>();
           //查询用户状态为1的数据
                predicate = predicate.And(x => x.status == 1);
    
                if (!string.IsNullOrEmpty(name))
                {
             //如果查询的用户名不为空,则拼接表达式 predicate
    = predicate.And(x => x.name == name); } var list = bll.GetList<UserInfo>(predicate,o=>o.orderno);

    其中UserInfo为用户表的实体类。

    list即为查询的结果。

  • 相关阅读:
    大量 TIME_WAIT 状态 TCP 连接,对业务有什么影响?怎么处理
    点击按钮保存当前页面为图片html2canvas
    浅谈webpack优化
    nginx配置
    table表格边框线问题
    git push到指定仓库
    No bean named 'xxx' is defined错误,原因及解决方案
    关于The requested list key 'map' could not be resolved as a collection/array/map/enumera...
    Tomcat网页加载过慢的排查调整time_wait连接过多
    MySQL information_schema 系统库
  • 原文地址:https://www.cnblogs.com/zhuiyi/p/5329771.html
Copyright © 2011-2022 走看看