第一次分享代碼,不足或不對之處請指正。。
需求:微信端傳遞不同的參數調用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); } } }
測試結果:
傳遞一個參數



傳遞兩個參數時



