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 = ; 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 > )
{
sbWhereSql.Insert(, " 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 = -;
try
{
int.Parse(obj.ToString());
}
catch { d = -; }
if (d == -) 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 < || this.PageSize <=
|| 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 > ? : ); //当前页数据
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, "")
.ToList<table>();
//也可以先拼接好参数,再一次性传入
var params = new DbParameter[];
params[] = DbSession.Default.Db.DbProviderFactory.CreateParameter();
params[].DbType = DbType.String;
params[].ParameterName = "@name";
params[].Value = "ITdos";
params[] = DB.Context.Db.DbProviderFactory.CreateParameter();
params[].DbType = DbType.Int32;
params[].ParameterName = "@id";
params[].Value = ;
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);
}
}
}
测试结果:
传递一个参数



传递两个参数时



C# WebAPI分页实现分享的更多相关文章
- bootstrap table 服务器端分页例子分享
这篇文章主要介绍了bootstrap table 服务器端分页例子分享,需要的朋友可以参考下 1,前台引入所需的js 可以从官网上下载 复制代码代码如下: function getTab(){var ...
- H5+.Net Webapi集成微信分享前后端代码 微信JS-SDK wx.onMenuShareTimeline wx.onMenuShareAppMessage
说明: 1/因为赚麻烦这里没有使用数据库或服务器缓存来存储access_token和jsapi_ticket,为了方便这里使用了本地的xml进行持久化这两个值以及这两个值的创建时间和有限期限. 2/每 ...
- PHP分页类分享
/** * 获取分页的HTML内容 * @param integer $page 当前页 * @param integer $pages 总页数 * @param string $url 跳转url地 ...
- webapi+entityframework分享
1. webapi允许跨域的增删改查要在web.config中加入以下文字 <system.webServer> <validation validateIntegratedMode ...
- phpcmsv9多表联合查询分页功能实现
phpcms v9里面自带的listinfo分页函数蛮好用的,可惜啊.不支持多表查询并分页. 看了一下前台模板层支持get标签,支持多表查询,支持分页.刚好可以把这个功能搬到后台来使用. 我们现在对g ...
- 经验分享:10个简单实用的 jQuery 代码片段
尽管各种 JavaScirpt 框架和库层出不穷,jQuery 仍然是 Web 前端开发中最常用的工具库.今天,向大家分享我觉得在网站开发中10个简单实用的 jQuery 代码片段. 您可能感兴趣的相 ...
- 基于OWIN WebAPI 使用OAuth授权服务【客户端验证授权(Resource Owner Password Credentials Grant)】
适用范围 前面介绍了Client Credentials Grant ,只适合客户端的模式来使用,不涉及用户相关.而Resource Owner Password Credentials Grant模 ...
- 使用DataList 分页方法
什么是DataList我想应该不需要解释了,接下来分享本人在项目里使用到的通过DataList进行分页展示方法. 首先在ASPX页面添加一个DataList(后面都简称DL)控件,示例代码如下: &l ...
- ThinkPHP分页实例
ThinkPHP分页实例 (2014-09-20 15:34:36) 很多人初学thinkphp时,不太熟悉thinkphp的分页使用方法,现在将自己整理的分页方法分享下,有需要的朋友可以看看. ...
随机推荐
- 论文阅读:Siam-RPN
摘要 Siam-RPN提出了一种基于RPN的孪生网络结构.由孪生子网络和RPN网络组成,它抛弃了传统的多尺度测试和在线跟踪,从而使得跟踪速度非常快.在VOT实时跟踪挑战上达到了最好的效果,速度最高16 ...
- Wannafly挑战赛1 C MMSet2 虚树
题目链接:https://www.nowcoder.com/acm/contest/15/C 思路:虚树,取两点间的lca,构造成一颗新的树:求(直径+1)/2即可 #pragma comment(l ...
- 分页查询最好加排序(order by)
昨天,与外部化系统对接时,发现有一个数据一直咩有集成到,双方各自排查了自己系统的代码,都觉得逻辑非常简单,无法就是一个分页查询而已. 问题就出在这个分页查询上. 为了说明当时问题发生的情景,我模拟了一 ...
- 20175317 《Java程序设计》第七周学习总结
20175317 <Java程序设计>第七周学习总结 教材学习内容总结 第七周我学习了教材第八章的内容,学习了许多常用实用类,有以下内容: String类 1. 如何构造String对象 ...
- webdirver.Chrom() selenium webdirver调用谷歌浏览器的问题解决
第一个坑: 没有将谷歌驱动放到 /usr/local/bin 目录下 第二个坑: 没有将谷歌浏览器.exe放在 /usr/local/bin 目录下(注意:驱动和浏览器在一个路径下才能使 ...
- flex属性介绍
- 瀑布流布局(等宽不等高jQuery)
在百度上看见的好多都是引用Masonry插件 ,之后我自己尝试了一个没有使用插件的 <body> <div id="main"> <div cla ...
- JavaJDK8新特性相关知识整理
1.新增接口默认方法和接口静态方法 接口默认方法用default关键字修饰,与抽象方法不同之处在于抽象方法必须要求实现,而默认方法没有这个要求,默认方法本身已经有具体的实现,所有的接口实现类将 ...
- 初识ldap
什么是LDAP? LDAP的英文全称是Lightweight Directory Access Protocol,一般都简称为LDAP.它是基于X.500标准的, 但是简单多了并且可以根据需要定制.与 ...
- 多个yml文件的读取方式
1配置pom.xml文件,以下配置将默认激活-dev.yml配置文件<profiles> <profile> <id>dev&l ...