第一次分享代码,不足或不对之处请指正。。

需求:微信端传递不同的参数调用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分页实现分享的更多相关文章

  1. bootstrap table 服务器端分页例子分享

    这篇文章主要介绍了bootstrap table 服务器端分页例子分享,需要的朋友可以参考下 1,前台引入所需的js 可以从官网上下载 复制代码代码如下: function getTab(){var ...

  2. H5+.Net Webapi集成微信分享前后端代码 微信JS-SDK wx.onMenuShareTimeline wx.onMenuShareAppMessage

    说明: 1/因为赚麻烦这里没有使用数据库或服务器缓存来存储access_token和jsapi_ticket,为了方便这里使用了本地的xml进行持久化这两个值以及这两个值的创建时间和有限期限. 2/每 ...

  3. PHP分页类分享

    /** * 获取分页的HTML内容 * @param integer $page 当前页 * @param integer $pages 总页数 * @param string $url 跳转url地 ...

  4. webapi+entityframework分享

    1. webapi允许跨域的增删改查要在web.config中加入以下文字 <system.webServer> <validation validateIntegratedMode ...

  5. phpcmsv9多表联合查询分页功能实现

    phpcms v9里面自带的listinfo分页函数蛮好用的,可惜啊.不支持多表查询并分页. 看了一下前台模板层支持get标签,支持多表查询,支持分页.刚好可以把这个功能搬到后台来使用. 我们现在对g ...

  6. 经验分享:10个简单实用的 jQuery 代码片段

    尽管各种 JavaScirpt 框架和库层出不穷,jQuery 仍然是 Web 前端开发中最常用的工具库.今天,向大家分享我觉得在网站开发中10个简单实用的 jQuery 代码片段. 您可能感兴趣的相 ...

  7. 基于OWIN WebAPI 使用OAuth授权服务【客户端验证授权(Resource Owner Password Credentials Grant)】

    适用范围 前面介绍了Client Credentials Grant ,只适合客户端的模式来使用,不涉及用户相关.而Resource Owner Password Credentials Grant模 ...

  8. 使用DataList 分页方法

    什么是DataList我想应该不需要解释了,接下来分享本人在项目里使用到的通过DataList进行分页展示方法. 首先在ASPX页面添加一个DataList(后面都简称DL)控件,示例代码如下: &l ...

  9. ThinkPHP分页实例

    ThinkPHP分页实例 (2014-09-20 15:34:36)   很多人初学thinkphp时,不太熟悉thinkphp的分页使用方法,现在将自己整理的分页方法分享下,有需要的朋友可以看看. ...

随机推荐

  1. jsp servlet table 集合list 数据 绑定

    删除 前端

  2. Generator

    基本概念 Generator函数是ES6提供的一种异步编程解决办法,语法行为与传统函数完全不同. Generator函数有多种理解角度.语法上,首先可以把它理解成,Generator函数是一个状态机, ...

  3. setTimeout setInterval 计时器

    setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. 返回值:返回一个 ID(数字),可以将这个ID传递给 clearTimeout() 来取消执行. 案例: 点击按钮开始,停止时 ...

  4. arcgis raster clip and mask difference 栅格 提取 clip 和 mask 方法的区别

    建议使用 数据管理工具下的此工具进行操作: 在选择参数时,注意做如下选择,可以保证栅格不会轻微错开: 也就是勾选第一个,而不勾选第二个 看看效果,使用mask得到的裁剪结果,注意有错开现象: 使用cl ...

  5. 如何查看linux服务器内存使用情况

    1. free命令 free 命令显示系统使用和空闲的内存情况,包括物理内存.交互区内存(swap)和内核缓冲区内存. 直接输入free命令,显示如下   free命令默认是显示单位kb,可以采用fr ...

  6. MVC与MVVM关系图解

  7. anaconda的使用总结

    致python初学者:Anaconda入门使用指南 http://python.jobbole.com/87522/ Anaconda使用总结 http://python.jobbole.com/86 ...

  8. dedecmsV5.7织梦后台更新文章,发布时间不自动更新

    问题:dedecmsV5.7后台修改文章的时候,会更新发布时间,需求是不自动更新时间,还是当时的发布时间 解决: 1.修改后台文件夹/templets/archives_edit.htm,articl ...

  9. XV Open Cup named after E.V. Pankratiev. GP of Central Europe (AMPPZ-2014)--B.Petrol

    多源最短路+并查集 #include <bits/stdc++.h> using namespace std; #define rep(i, j, k) for (int i = int( ...

  10. 人生苦短,我用python(目录)

    一.python基础篇 python中闭包及延时绑定问题 python中的装饰器.生成器 二.前端 bootstrap框架 BOM&DOM JavaScript中的词法分析 三.数据库 mys ...