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} ";
}
}
}
以上代码需要在项目中,引入如下程序集:
开源代码下载地址 请根据使用的项目,自行选择编译指定项目,后获取dll,导入到自己的项目中.