C# WebAPI分頁實現分享


第一次分享代碼,不足或不對之處請指正。。

需求:微信端傳遞不同的參數調用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);
            }
        }
}

測試結果:

傳遞一個參數

 

 

 

傳遞兩個參數時

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM