第一次分享代码,不足或不对之处请指正。。
需求:微信端传递不同的参数调用WebAPI进行分页查询菜谱计划点评结果
思路:基于视图来查询,根据传递的不同参数拼接分页查询Sql来查询。
分页的sql如下
select * from 视图 where 排序字段 in( select top 每页数量 排序字段 from ( select top 每页数量 排序字段 from 视图 where条件 order by 排序字段 asc ) t )
首先建立参数模型类BasePageQueryInfo
/// <summary> /// 分页查询信息-基类 /// </summary> public class BasePageQueryInfo { /// <summary> /// 查询语句 /// </summary> protected string _querySql; /// <summary> /// 查询语句 /// </summary> public string QuerySql { get { return _querySql; } } /// <summary> /// 查询视图名称 /// </summary> protected string _view; /// <summary> /// 查询视图名称 /// </summary> public string View { get { return _view; } } /// <summary> /// 每页记录数 /// </summary> public int PageSize { get; set; } /// <summary> /// 当前页 /// </summary> public int Page { get; set; } /// <summary> /// 排序字段 /// </summary> public string OrderByField { get; set; } /// <summary> /// 排序/降序 /// </summary> public string OrderBy { get; set; } /// <summary> /// where查询条件 /// </summary> protected string _whereCondition; /// <summary> /// where查询条件 /// </summary> public string WhereCondition { get { return _whereCondition; } } /// <summary> /// where入参 /// </summary> protected List<SqlInParameter> _listSqlInParameter; /// <summary> /// where入参 /// </summary> public List<SqlInParameter> ListSqlInParameter { get { return _listSqlInParameter; } } /// <summary> /// 总条目数Sql /// </summary> protected string _totalCountSql; /// <summary> /// 总条目数Sql /// </summary> public string TotalCountSql { get { return _totalCountSql; } } /// <summary> /// 分页查询Sql /// </summary> protected string _pageSql; /// <summary> /// 分页查询Sql /// </summary> public string PageSql { get { return _pageSql; } } /// <summary> /// 初始化分页查询属性 /// </summary> /// <returns></returns> public bool InitPageQueryProperty() { try { //Where条件语句和入参 StringBuilder sbWhereSql = new StringBuilder(); Type t = this.GetType(); PropertyInfo[] properties = t.GetProperties().Where(x => !IsNullValue(x.GetValue(this))).ToArray(); _listSqlInParameter = new List<SqlInParameter>(); bool isFirst = true; for (int i = 0; i < properties.Length; i++) { PropertyInfo property = properties[i]; object propertyValueObj = property.GetValue(this); SqlConditionAttribute conditionAttr = property.GetCustomAttribute<SqlConditionAttribute>(); if (conditionAttr == null) continue; if (isFirst) { sbWhereSql.AppendFormat(" {0} {1} @{2} ", conditionAttr.SqlField, conditionAttr.CompareSymbol, conditionAttr.SqlField); isFirst = false; } else { sbWhereSql.AppendFormat(" And {0} {1} @{2} ", conditionAttr.SqlField, conditionAttr.CompareSymbol, conditionAttr.SqlField); } SqlInParameter inParam = new SqlInParameter(); inParam.DataType = conditionAttr.DataType; inParam.ParameterName = conditionAttr.SqlField; inParam.ParameterValue = propertyValueObj; inParam.IsVague = conditionAttr.CompareSymbol == CompareSymbol.LIKE; _listSqlInParameter.Add(inParam); } if (_listSqlInParameter.Count > 0) { sbWhereSql.Insert(0, " Where "); } _whereCondition = sbWhereSql.ToString(); //分页Sql StringBuilder sbPageSql = new StringBuilder(); sbPageSql.AppendFormat("select * from {0} where ", this.View); sbPageSql.Append(this.OrderByField); sbPageSql.Append(" in( select top "); sbPageSql.Append(this.PageSize); sbPageSql.Append(" "); sbPageSql.Append(this.OrderByField); sbPageSql.Append(" from ( select top ("); sbPageSql.Append(this.PageSize * this.Page); sbPageSql.Append(") "); sbPageSql.Append(this.OrderByField); sbPageSql.AppendFormat(" from {0} ", this.View); sbPageSql.Append(_whereCondition); sbPageSql.Append(" order by "); sbPageSql.Append(this.OrderByField); sbPageSql.Append(" "); sbPageSql.Append(this.OrderBy); sbPageSql.Append(" ) t )"); _pageSql = sbPageSql.ToString(); //总个数sql StringBuilder sbTotalSql = new StringBuilder(); sbTotalSql.AppendFormat("Select Count(1) From {0} ", this.View); sbTotalSql.Append(WhereCondition); _totalCountSql = sbTotalSql.ToString(); return true; } catch (Exception ex) { return false; } } private bool IsNullValue(object obj) { if (obj == null) return true; Type type = obj.GetType(); if (type.FullName == "System.Int32") { int d = -1; try { int.Parse(obj.ToString()); } catch { d = -1; } if (d == -1) return true; } else if (type.FullName == "System.String") { return string.IsNullOrWhiteSpace(obj.ToString()); } //其他待补充 return false; } /// <summary> /// 自检 /// </summary> /// <returns></returns> public bool SelfValidate() { string[] orderbys = new string[] { "asc","desc" }; if (this.Page < 0 || this.PageSize <= 0 || string.IsNullOrWhiteSpace(this.OrderBy) || !orderbys.Contains(this.OrderBy.ToLower()) || string.IsNullOrWhiteSpace(this.OrderByField)) { return false; } return true; } }
入参SqlInParameter
/// <summary> /// Sql入参信息 /// </summary> public class SqlInParameter { /// <summary> /// 参数名称 /// </summary> public string ParameterName { get; set; } /// <summary> /// 数据类型 /// </summary> public DbType DataType { get; set; } /// <summary> /// 参数值 /// </summary> public object ParameterValue { get; set; } /// <summary> /// 是否模糊参数查询 /// </summary> public bool IsVague { get; set; } }
参数模型属性SqlConditionAttribute,主要用来反射得到对应的查询字段,比较符号,生成SqlInParameter。
/// <summary> /// Sql条件属性 /// </summary> public class SqlConditionAttribute : Attribute { /// <summary> /// 对应Sql查询字段 /// </summary> public string SqlField { get; set; } /// <summary> /// 数据类型 /// </summary> public System.Data.DbType DataType { get; set; } /// <summary> /// 比较符号 /// </summary> public string CompareSymbol { get; set; } }
比较符号常量CompareSymbol
/// <summary> /// 比较符号 /// </summary> public class CompareSymbol { /// <summary> /// 等于 /// </summary> public const string EQUALS = "="; /// <summary> /// 不等于 /// </summary> public const string NOTEQUALS = "!="; /// <summary> /// Like /// </summary> public const string LIKE = "Like"; /// <summary> /// 大于 /// </summary> public const string GREATER = ">"; /// <summary> /// 大于等于 /// </summary> public const string GREATEREQUALS = ">="; /// <summary> /// 小于 /// </summary> public const string SMALLER = "<"; /// <summary> /// 小于等于 /// </summary> public const string SMALLEREQUALS = "<="; }
分页查询结果类
/// <summary> /// 分页结果数据 /// </summary> /// <typeparam name="T"></typeparam> public class PageResult<T> where T : class { /// <summary> /// 总记录数 /// </summary> public int Count { get; set; } /// <summary> /// 总页数 /// </summary> public int TotalPage { get; set; } /// <summary> /// 当前页 /// </summary> public int CurPage { get; set; } /// <summary> /// 当前页数据 /// </summary> public List<T> PageData { get; set; } }
分页查询器PageQuerier
/// <summary> /// 分页查询器 /// </summary> public class PageQuerier { /// <summary> /// 查询分页信息 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="dbSession"></param> /// <param name="pageQueryInfo"></param> /// <returns></returns> public static PageResult<T> Query<T>(DbSession dbSession,BasePageQueryInfo pageQueryInfo) where T : class { //总记录数 SqlSection countSqlSection = dbSession.FromSql(pageQueryInfo.TotalCountSql); AddInParameterToSqlSection(countSqlSection, pageQueryInfo.ListSqlInParameter); int totalCount = countSqlSection.ToFirst<int>(); //总页数 int totalPage = totalCount / pageQueryInfo.PageSize + (totalCount % pageQueryInfo.PageSize > 0 ? 1 : 0); //当前页数据 SqlSection pageSqlSection = dbSession.FromSql(pageQueryInfo.PageSql); AddInParameterToSqlSection(pageSqlSection, pageQueryInfo.ListSqlInParameter); List<T> lstData = pageSqlSection.ToList<T>(); PageResult<T> pageResult = new PageResult<T>() { Count = totalCount, TotalPage = totalPage, CurPage = totalPage > pageQueryInfo.Page ? pageQueryInfo.Page : totalPage, PageData = lstData }; return pageResult; } /// <summary> /// 向SqlSection追加参数 /// </summary> /// <param name="sqlSection"></param> /// <param name="pageQueryInfo"></param> private static void AddInParameterToSqlSection(SqlSection sqlSection,IEnumerable<SqlInParameter> sqlInParameters) { foreach (SqlInParameter inParam in sqlInParameters) { sqlSection.AddInParameter(inParam.ParameterName, inParam.DataType, inParam.IsVague ? "%" + inParam.ParameterValue + "%" : inParam.ParameterValue); } } }
笔者使用的是Dos.ORM来查询数据,该ORM中直接执行Sql示例如下
var list = DB.Context.FromSql("SELECT * FROM table WHERE name=@name AND id=@id") .AddInParameter("@name", DbType.String, "ITdos") .AddInParameter("@id", DbType.Int32, "1") .ToList<table>(); //也可以先拼接好参数,再一次性传入 var params = new DbParameter[2]; params[0] = DbSession.Default.Db.DbProviderFactory.CreateParameter(); params[0].DbType = DbType.String; params[0].ParameterName = "@name"; params[0].Value = "ITdos"; params[1] = DB.Context.Db.DbProviderFactory.CreateParameter(); params[1].DbType = DbType.Int32; params[1].ParameterName = "@id"; params[1].Value = 1; DB.Context.FromSql("SELECT * FROM table WHERE name=@name AND id=@id") .AddParameter(params) .ToDataTable();
接下来是具体的分页查询模型
/// <summary> /// 菜谱计划点评分页查询参数 /// </summary> public class FoodPlanCommentPageQueryInfo : BasePageQueryInfo { /// <summary> /// 菜谱计划点评分页查询参数 /// </summary> public FoodPlanCommentPageQueryInfo() { this._view = "V_FoodPlanComment"; this.OrderBy = "asc"; this.OrderByField = "CommentTime"; } /// <summary> /// MemberId /// </summary> [SqlCondition(SqlField = "MemberGuid", DataType = DbType.Guid, CompareSymbol = CompareSymbol.EQUALS)] public string MemberGuid { get; set; } /// <summary> /// OpenId /// </summary> [SqlCondition(SqlField = "OpenId", DataType = DbType.String, CompareSymbol = CompareSymbol.EQUALS)] public string OpenId { get; set; } /// <summary> /// 菜谱计划Id /// </summary> [SqlCondition(SqlField = "FoodPlanGuid", DataType = DbType.Guid, CompareSymbol = CompareSymbol.EQUALS)] public string FoodPlanGuid { get; set; } }
WebAPI实现
public class FoodPlanCommentController : BaseApiController { /// <summary> /// 获取菜谱计划点评信息 /// </summary> /// <param name="param"></param> /// <returns></returns> public ResponseResult<PageResult<FoodPlanComment>> Get(FoodPlanCommentPageQueryInfo param) { if (!param.SelfValidate()) { return ResponseResult<PageResult<FoodPlanComment>>.Custome(APICode.InValidParams); } if (string.IsNullOrWhiteSpace(param.FoodPlanGuid) && string.IsNullOrWhiteSpace(param.MemberGuid) && string.IsNullOrWhiteSpace(param.OpenId)) { return ResponseResult<PageResult<FoodPlanComment>>.Custome(APICode.InValidParams, "FoodPlanGuid,MemberGuid,OpenId必须存在一个查询参数"); } if (!param.InitPageQueryProperty()) { return ResponseResult<PageResult<FoodPlanComment>>.Custome(APICode.InternalError, "分页查询模型绑定失败"); } try { PageResult<FoodPlanComment> pageResult = PageQuerier.Query<FoodPlanComment>(DBContext.Instance, param); return ResponseResult<PageResult<FoodPlanComment>>.Success(pageResult); } catch (Exception ex) { this.Error(ex); return ResponseResult<PageResult<FoodPlanComment>>.Custome(APICode.InternalError); } } }
测试结果:
传递一个参数
传递两个参数时