• 001 SqlSugar 查询扩展


    001 SqlSugar 查询扩展


    博客园Id:13041713


    提出问题

    有的时候我们在进行单表查询时,可能需要的条件有很多,但是,我们需要一一来判断,查询参数是否为空,如果为空就不使用这个字段来作为查询条件,在这种情况下,我们会写大量的if语句,这是一种重复的工作,我们应该如何避免这样的问题呢?

    下面是重复代码的示例程序代码:

    /// <summary>
    /// 加载登录信息
    /// </summary>
    /// <returns></returns>
    public IActionResult LoadAllLoginInfo(LoginInfoReqDto loginInfoReqDto)
    {
    
        var totalCount = 0;
    
        var querySqlQueryable = this._context.Queryable<sys_loginfo>();
    
    
        if (!string.IsNullOrEmpty(loginInfoReqDto.LoginName))
        {
            querySqlQueryable = querySqlQueryable.Where(x => x.loginname == loginInfoReqDto.LoginName);
        }
    
        if (!string.IsNullOrEmpty(loginInfoReqDto.LoginIp))
        {
            querySqlQueryable = querySqlQueryable.Where(x => x.loginip == loginInfoReqDto.LoginIp);
        }
       
    
        if (loginInfoReqDto.StartTime != DateTime.MinValue)
        {
            querySqlQueryable = querySqlQueryable.Where(x => x.logintime >= loginInfoReqDto.StartTime);
        }
    
        if (loginInfoReqDto.EndTime != DateTime.MinValue)
        {
            querySqlQueryable = querySqlQueryable.Where(x => x.logintime <= loginInfoReqDto.EndTime);
        }
    
        var queryResult = querySqlQueryable.OrderBy(x => x.id, OrderByType.Desc)
            .ToPageList(loginInfoReqDto.Page, loginInfoReqDto.Limit, ref totalCount);
    
        var result = new LoginInfoResDto
        {
            Code = 0,
            Msg = "查询成功",
            Count = totalCount,
            Data = queryResult
        };
    
        return Json(result);
    }#
    

    上面代码中,我们可以看到有很多拼装表达式树的过程代码. 这样的话,往往需要我们写很多无意义的冗余代码.

    下面我们把代码精简一下.

    简化代码如下:

    /// <summary>
    /// 加载登录信息
    /// </summary>
    /// <returns></returns>
    public IActionResult LoadAllLoginInfo(LoginInfoReqDto loginInfoReqDto)
    {
    
        var totalCount = 0;
    
        var querySqlQueryable = this._context.Queryable<sys_loginfo>();
        querySqlQueryable = this._context.Queryable<sys_loginfo>().Where(loginInfoReqDto);
    	
        var queryResult = querySqlQueryable.OrderBy(x => x.id, OrderByType.Desc)
            .ToPageList(loginInfoReqDto.Page, loginInfoReqDto.Limit, ref totalCount);
    
        var result = new LoginInfoResDto
        {
            Code = 0,
            Msg = "查询成功",
            Count = totalCount,
            Data = queryResult
        };
    
        return Json(result);
    }

    通过上面的代码,我们简化了很多不需要的if语句拼装表达式树的过程.

    核心SqlSugar查询扩展代码如下:

    using System.Collections.Generic;
    using System.Text;
    using System.Reflection;
    
    namespace SqlSugar
    {
        public static class SqlSugarExt
        {
            /// <summary>
            /// 根据条件对象查询数据
            /// </summary>
            /// <typeparam name="T">表实体对象</typeparam>
            /// <param name="sugarQueryable">sugar查询对象</param>
            /// <param name="whereObj">查询实体</param>
            /// <returns></returns>
            public static ISugarQueryable<T> Where<T>(this ISugarQueryable<T> sugarQueryable, object whereObj)
            {
                var sugarQueryableWhere = sugarQueryable;
    
                var whereObjType = whereObj.GetType();
                var whereDic = new Dictionary<string, object>();      //装载where条件
                var inDic = new Dictionary<string,List<int>>();       //装载in条件
    
                foreach (var property in whereObjType.GetProperties())
                {
                    var curName = property.Name;
                    if (property.PropertyType.Name.Equals("List`1"))  //集合
                    {
                        var curValue = property.GetValue(whereObj, null);
                        inDic.Add(curName, (List<int>)curValue);
                    }
                    else
                    {
                        var curValue = property.GetValue(whereObj, null);
                        if (curValue==null) continue;                //排除参数值为null的查询条件
                        whereDic.Add(curName.ToLower(), curValue);
                    }
                }
    
                var dbModelType = typeof(T);
    
                var expSb = new StringBuilder();
    
                foreach (var property in dbModelType.GetProperties())      //遍历dbModel属性
                {
                    foreach (var (key, value) in whereDic)                     
                    {
                        if (property.Name.ToLower() != key) continue;
    
                        expSb.Append(ProcessExp(property,value));          //拼接where条件
                        expSb.Append(" and ");
                    }
                }
    
                if (expSb.Length != 0)                                     //转换where条件表达式树
                {
                    var exp = expSb.ToString().Remove(expSb.Length - 4, 4);
    
                    var e = System.Linq.DynamicCore.DynamicExpression.ParseLambda<T, bool>(exp);
    
                    sugarQueryableWhere = sugarQueryable.Where(e);
                }
    
    
                if (inDic.Count == 0) return sugarQueryableWhere;
    
                foreach (var (key, value) in inDic)                       //转换in条件表达式树
                {
                    var e2 = System.Linq.DynamicCore.DynamicExpression.ParseLambda<T, object>(key);
                    sugarQueryableWhere = sugarQueryableWhere.In(e2, value);
                }
    
                return sugarQueryableWhere;
            }
    
            /// <summary>
            /// 处理表达式树拼接
            /// </summary>
            /// <param name="property"></param>
            /// <param name="value"></param>
            /// <returns></returns>
            private static string ProcessExp(PropertyInfo property,object value)
            {
               
                //引用类型 此处只考虑string类型的情况
                if (!property.PropertyType.IsValueType) return $"{property.Name} = "{value}" ";
    
                //可空值类型 此处只考虑简单值类型
                if (property.PropertyType.Name.Equals("Nullable`1"))   
                {
                    if (property.PropertyType.GenericTypeArguments[0].Name.Equals("DateTime"))
                    {
                        return $"{property.Name} = Convert.ToDateTime("{value}") ";
                    }
                        
                    return $"{property.Name} = {value} ";
                }
    
                //值类型  此处只考虑简单值类型
                if (property.PropertyType.Name.Equals("DateTime"))  
                {
                    return $"{property.Name} = Convert.ToDateTime("{value}") ";
                }
    
                return $"{property.Name} = {value} ";
    
                
            }
    
           
            
        }
    }

    以上代码需要在项目中,引入如下程序集:
    动态Linq生成

    开源代码下载地址 请根据使用的项目,自行选择编译指定项目,后获取dll,导入到自己的项目中.

  • 相关阅读:
    Python中的魔法方法【技能突破】
    Python简明教程:面向对象【新手必学】
    No such file or directory
    LaTeX Error: File ''picins.sty'' not Found.
    GCC编译过程中的各种not declared in this scope
    20.有效的括号-力扣
    c++标准库bitset文件
    c++标准库windows.h文件
    warning: control reaches end of non-void function
    c++标准库iostream文件
  • 原文地址:https://www.cnblogs.com/HelloZyjS/p/13041713.html
Copyright © 2020-2023  润新知