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