这是一篇运用在MyFrameWork(YZR框架)上的RSqlBuilder类的介绍,它主要是对Sql语句的补充支持,在RPro之外以链式编程,类似于数据访问层的方式存在。
1.开始之前先说明一下IDataBase 接口,RPro 类。
IDataBase action = RUtility.Instance.GetDbUtility(TableName);
获得的就是框架的数据操作类(RAction,RMotion),IDataBase 目前兼容Oracle和SqlServer数据库.
RPro rp = new RPro([_dbUtility]);
获取的就是框架存储过程以及Sql的操作类,RPro目前兼容Oracle和SqlServer数据库。(对于sql语句需要开发者根据自己选择的数据库进行编写相应的sql格式)
2.进入主题
RSqlBuilder是对RPro的补充,能统一Sql语句(不区别数据库,写法一样),支持链接编程,支持AOP拦截。(目前版本只用于查询 ,不用于新增,删除,更新)
RRunnable run = rp.ExecuteQuerySqlBuilder(rsb);
返回的结果是RRunnable对象,主要的目的是为了更好的获取运行结果,RRunnable类有相应的异常处理以及内置数据转化器(List,DataTable,Int,String等)
namespace YZR.Data{ using System.Collections; using System.Reflection; ////// Create By YZR 2016.03.01 /// 用于查询 不用于新增,删除,更新 /// public sealed class RSqlBuilder { private string actionName; public string ActionName { get { return actionName; } set { actionName = value; } } private string columnName; public string ColumnName { get { return columnName; } set { columnName = value; } } private string colName;//作为子查询的别名列 public string ColName { get { return colName; } set { colName = value; } } private string dataSource; public string DataSource { get { return dataSource; } set { dataSource = value; } } private string tableName; public string TableName { get { return tableName; } set { tableName = value; } } private Listwheres; public List Wheres { get { return wheres; } set { wheres = value; } } private RSqlBuilder rsb;//作为内置子查询对象 public RSqlBuilder Rsb { get { return rsb; } set { rsb = value; } } private QueryPattern pattern = QueryPattern.Where; public QueryPattern Pattern { get { return pattern; } set { pattern = value; } } private bool isSubQuery = false; public bool IsSubQuery { get { return isSubQuery; } set { isSubQuery = value; } } private bool isJoinQuery = false; public bool IsJoinQuery { get { return isJoinQuery; } set { isJoinQuery = value; } } public JoinClass jc { get; set; } public RRunnable innerRunnable { get; set; } private RSqlBuilder innerRsqlBuilder; public RSqlBuilder InnerRsqlBuilder { get { return innerRsqlBuilder; } set { innerRsqlBuilder = value; } } private int topCount; private string orderColumn; private OrderType orderType;//排序方式 private Pager pager; public Pager Pager { get { return pager; } set { pager = value; } } private bool QueryTotalCount = false; private List countWheres; private bool QueryDistinct = false; public RSqlBuilder() { this.innerRsqlBuilder = this; } public RSqlBuilder(string _actionName, string _columnName, string _dataSource) { this.actionName = _actionName; this.columnName = _columnName; this.dataSource = _dataSource; this.innerRsqlBuilder = this; } public RSqlBuilder(string _actionName, string _columnName, string _dataSource, List wheres) { this.actionName = _actionName; this.columnName = _columnName; this.dataSource = _dataSource; this.wheres = wheres; this.innerRsqlBuilder = this; } public RSqlBuilder(string _actionName, string _columnName, string _dataSource, string tableName) { this.actionName = _actionName; this.columnName = _columnName; this.dataSource = _dataSource; this.tableName = tableName; this.innerRsqlBuilder = this; } public RSqlBuilder(string _actionName, string _columnName, string _dataSource, string tableName, List wheres) { this.actionName = _actionName; this.columnName = _columnName; this.dataSource = _dataSource; this.tableName = tableName; this.wheres = wheres; this.innerRsqlBuilder = this; } /// /// /// /// /// /// 作为where语句的 列名 in (....) /// /// /// /// /// public RSqlBuilder(string _actionName, string _columnName, string _colName, string _dataSource, string tableName, Listwheres, RSqlBuilder rsb, QueryPattern qp) { this.actionName = _actionName; this.columnName = _columnName; this.dataSource = _dataSource; this.tableName = tableName; this.wheres = wheres; this.rsb = rsb; this.Pattern = qp; this.isSubQuery = true; this.innerRsqlBuilder = this; this.colName = _colName; } public RSqlBuilder(string _actionName, string _columnName, string tableName, List wheres, RSqlBuilder rsb, QueryPattern qp) { this.actionName = _actionName; this.columnName = _columnName; this.tableName = tableName; this.wheres = wheres; this.rsb = rsb; this.Pattern = qp; this.isSubQuery = true; this.innerRsqlBuilder = this; } public void ToSql() { Rsql rs = new Rsql(); if (IsJoinQuery) { rs.JObject = jc; //rs.IsJoinQuery = true; rs.IsJoinQuery = IsJoinQuery; //isJoinQuery = false;//完成传导之后恢复isJoinQuery值 rs.ActionName = RAopEnum.Select.ToString(); rs.ColumnName = jc.ColumnName; rs.DataSource = jc.MainTableName + "-" + jc.JoinTableName; rs.TableName = null; rs.Wheres = jc.Wheres; } else { rs.ActionName = this.actionName; rs.ColumnName = this.columnName; rs.DataSource = this.dataSource; rs.TableName = this.tableName; rs.Wheres = this.wheres; rs.subRsb = this.rsb; rs.pattern = this.pattern; } rs.IsSubQuery = this.isSubQuery; rs.TopCount = innerRsqlBuilder.topCount; rs.orderType = innerRsqlBuilder.orderType; rs.OrderColumn = innerRsqlBuilder.orderColumn; rs.innerPager = innerRsqlBuilder.pager; rs.QueryTotalCount = innerRsqlBuilder.QueryTotalCount; rs.QueryDistinct = innerRsqlBuilder.QueryDistinct; rs.IsToSql = true; _rsqlExpress = rs; } public void SetAction(RAopEnum rEnum) { this.actionName = rEnum.ToString(); } public void SetColumn(string[] colNames) { StringBuilder _colNames = new StringBuilder(); if (colNames.Length <= 0) { this.columnName = "*"; return; } foreach (string item in colNames) { _colNames.Append(item + ","); } _colNames = _colNames.Remove(_colNames.Length - 1, 1); this.columnName = _colNames.ToString(); } public void SetColumn(string colNames) { this.columnName = colNames; } public void SetColumn() { this.columnName = "*"; } public void SetDataSoruce(TableNames tableName) { this.dataSource = tableName.ToString(); } private Rsql _rsqlExpress = new Rsql(); public Rsql RsqlExpress { get { return _rsqlExpress; } set { _rsqlExpress = value; } } static RSqlBuilder() { } public static RSqlBuilder Join(string table1, string table2, List list, List wheres)//考虑返回值,链表操作 { string[] names = new string[2] { table1, table2 }; Dictionary dic = new Dictionary (); RSqlBuilder rsb = new RSqlBuilder(); if (table1 == table2) { dic.Add("ERROR", "表名出现异常"); RRunnable run = new RRunnable("表名重复", 0, dic); rsb.innerRunnable = run; return rsb; } return Join(names, list, wheres); } private static bool func(string[] tableNames) { ArrayList al = new ArrayList(); foreach (string item in tableNames) { if (al.Contains(item)) { return true; } else { al.Add(item); } } return false; } public static RSqlBuilder Join(string[] tableNames, List list, List wheres) { Dictionary dic = new Dictionary (); RSqlBuilder rsb = new RSqlBuilder(); if (func(tableNames)) { dic.Add("ERROR", "表名出现异常"); RRunnable run = new RRunnable("表名重复", 0, dic); rsb.innerRunnable = run; return rsb; } if (list == null || list.Any() == false) { dic.Add("ERROR", "连接语句的on谓词出现异常"); RRunnable run = new RRunnable("on谓词的键值对不能为空,而且个数必须1个或以上", 0, dic); rsb.innerRunnable = run; return rsb; } if (tableNames == null || tableNames.Length < 1) { dic.Add("ERROR", "表名出现异常"); RRunnable run = new RRunnable("表名不能为空,而且个数必须1个或以上", 0, dic); rsb.innerRunnable = run; return rsb; } //连接操作 JoinClass myJoin = new JoinClass(); myJoin.MainTableName = tableNames[0]; //myJoin.JoinTableName = table2; myJoin.JoinType = JoinType.Inner; myJoin.Wheres = wheres; myJoin.ComplexJoin = false;//默认 string joinTable = string.Empty; ArrayList al = new ArrayList(); string onStr = string.Empty; if (list != null) { if (list.Any()) { foreach (OnKey item in list) { onStr += item.MainKey + " = " + item.JoinKey + " and "; } } } myJoin.OnString = onStr.Substring(0, onStr.Length - 4); if (tableNames.Length == 1)//内连接 { dic.Add("ERROR", "不支持自连接"); RRunnable run = new RRunnable("不支持自连接", 0, dic); rsb.innerRunnable = run; return rsb; //myJoin.JoinType = JoinType.Self; //myJoin.JoinTableName = myJoin.MainTableName; //myJoin.ColumnName = myJoin.MainTableName + ".*"; } else { Type type = typeof(TableNames); string[] tbNames = type.GetEnumNames(); bool error = false; foreach (string item in tableNames) { if (tbNames.Contains(item) == false) { error = true; break; } } if (error) { dic.Add("ERROR", "表名输入有误,请检车Entity"); RRunnable run = new RRunnable("找不到指定表名", 0, dic); rsb.innerRunnable = run; return rsb; } if (tableNames.Length > 2) { myJoin.ComplexJoin = true; } foreach (string table in tableNames) { if (table != myJoin.MainTableName) { joinTable += table + ","; } string path = AppDomain.CurrentDomain.BaseDirectory; Assembly ass = Assembly.LoadFrom(path + "bin\\YZR.Entity.dll"); Type t = ass.GetType("YZR.Entity." + table); string[] names = t.GetEnumNames(); int i = 0; foreach (string item in names) { bool flag = true; string value = item; string asString = string.Empty; while (flag) { if (al.Contains(value)) { i++; value = value + i; asString = item + " " + value;//别名 } else { flag = false; al.Add(value); } } if (string.IsNullOrEmpty(asString)) { myJoin.ColumnName += " " + table + "." + value + ","; } else { myJoin.ColumnName += " " + table + "." + asString + ","; } } } myJoin.JoinTableName = joinTable.Substring(0, joinTable.Length - 1); myJoin.ColumnName = myJoin.ColumnName.Substring(0, myJoin.ColumnName.Length - 1); } //jc = myJoin; //isJoinQuery = true; RSqlBuilder r = new RSqlBuilder(); r.IsJoinQuery = true; r.jc = myJoin; return r; } public static RSqlBuilder Select(string _columnName, string _dataSource, List wheres) { return new RSqlBuilder(RAopEnum.Select.ToString(), _columnName, _dataSource, wheres); } public static RSqlBuilder Select(string _columnName, string _dataSource, string tableName, List wheres) { return new RSqlBuilder(RAopEnum.Select.ToString(), _columnName, _dataSource, tableName, wheres); } /// /// where式子查询 /// /// /// 作为where语句的 "列名_colName" in (.....) /// /// /// /// ///public static RSqlBuilder SubSelectWhere(string _columnName, string _colName, string _dataSource, string tableName, List wheres, RSqlBuilder rsb) { return new RSqlBuilder(RAopEnum.Select.ToString(), _columnName, _colName, _dataSource, tableName, wheres, rsb, QueryPattern.Where); } public static RSqlBuilder SubSelectForm(string _columnName, string tableName, List wheres, RSqlBuilder rsb) { return new RSqlBuilder(RAopEnum.Select.ToString(), _columnName, tableName, wheres, rsb, QueryPattern.From); } public RSqlBuilder Top(int count) { this.innerRsqlBuilder.topCount = count; return this.innerRsqlBuilder; } public RSqlBuilder OrderByAsc(string Column) { this.innerRsqlBuilder.orderColumn = Column; this.innerRsqlBuilder.orderType = OrderType.Asc; return this.innerRsqlBuilder; } public RSqlBuilder OrderByAsc(Enum Column) { return OrderByAsc(Column.ToString()); } public RSqlBuilder OrderByDesc(string Column) { this.innerRsqlBuilder.orderColumn = Column; this.innerRsqlBuilder.orderType = OrderType.Desc; return this.innerRsqlBuilder; } public RSqlBuilder OrderByDesc(Enum Column) { return OrderByDesc(Column.ToString()); } /// /// 分页 /// /// 所有查询的列 /// 别名 /// 开始索引 /// 结束索引 /// 排序列,一般主键 ///public RSqlBuilder Page(string colName, string tableName, int StartIndex, int LastIndex, string orderCol, List wheres) { this.innerRsqlBuilder.pager = new Pager(colName, tableName, StartIndex, LastIndex, orderCol, wheres); return this.innerRsqlBuilder; } public RSqlBuilder Page(int PageIndex, int PageSize, string colName, string tableName, string orderCol, List wheres) { int StartIndex = (PageIndex - 1) * PageSize; int LastIndex = PageIndex * PageSize; this.innerRsqlBuilder.pager = new Pager(colName, tableName, StartIndex, LastIndex, orderCol, wheres); return this.innerRsqlBuilder; } /// /// 没有加上wheres /// /// ///public RSqlBuilder Count(List wheres) { innerRsqlBuilder.QueryTotalCount = true; return innerRsqlBuilder; } public RSqlBuilder Count() { innerRsqlBuilder.QueryTotalCount = true; return innerRsqlBuilder; } public RSqlBuilder Distinct() { innerRsqlBuilder.QueryDistinct = true; return innerRsqlBuilder; } public RSqlBuilder Clear() { return new RSqlBuilder(); } } public enum QueryPattern { From, Where } public class JoinClass { private string mainTableName; public string MainTableName { get { return mainTableName; } set { mainTableName = value; } } private string joinTableName; public string JoinTableName { get { return joinTableName; } set { joinTableName = value; } } private JoinType joinType; public JoinType JoinType { get { return joinType; } set { joinType = value; } } public string OnString { get; set; } private List wheres; public List Wheres { get { return wheres; } set { wheres = value; } } private string columnName; public string ColumnName { get { return columnName; } set { columnName = value; } } private bool complexJoin = false; public bool ComplexJoin { get { return complexJoin; } set { complexJoin = value; } } } public enum JoinType { Left, Right, Inner, Self } public class OnKey { private string mainKey; public string MainKey { get { return mainKey; } set { mainKey = value; } } private string joinKey; public string JoinKey { get { return joinKey; } set { joinKey = value; } } public OnKey(string mainKey, string joinKey) { this.mainKey = mainKey; this.joinKey = joinKey; } } public enum OrderType { Asc, Desc } public class Pager { private string colName; public string ColName { get { return colName; } set { colName = value; } } private string tableName; public string TableName { get { return tableName; } set { tableName = value; } } private int startIndex; public int StartIndex { get { return startIndex; } set { startIndex = value; } } private int lastIndex; public int LastIndex { get { return lastIndex; } set { lastIndex = value; } } private string orderCol; public string OrderCol { get { return orderCol; } set { orderCol = value; } } private List wheres; public List Wheres { get { return wheres; } set { wheres = value; } } public Pager(string colName, string tableName, int startIndex, int lastIndex, string orderCol, List wheres) { this.colName = colName; this.tableName = tableName; this.startIndex = startIndex; this.lastIndex = lastIndex; this.orderCol = orderCol; this.wheres = wheres; } }}
3.Demo
////// RSqlBuilder /// ///public string RExecute() { RPro rp = new RPro(); rp.ROpen(); List list = new List (); //list.Add(new RWhere(" and ", "UserName", "=", "YZR")); list.Add(new RWhere(" and ", TableNames.UserInfo.ToString() + "." + UserInfo.UserID.ToString(), "in", "1,2,3,4")); //================Begin SubQuery============================================================ //RSqlBuilder ParentRsb = new RSqlBuilder(RAopEnum.Select.ToString(), "UserName", "TestTable"); //操作,列名,数据源,别名,条件 //RSqlBuilder rsb = new RSqlBuilder(RAopEnum.Select.ToString(), "*","PrizeID", "TestTable", "Alias",null,ParentRsb,QueryPattern.Where);//子查询作为数据源 //RSqlBuilder rsb = new RSqlBuilder(RAopEnum.Select.ToString(), "*", "Alias", list, ParentRsb, QueryPattern.From); //RSqlBuilder rsb = new RSqlBuilder(RAopEnum.Select.ToString(), "*", "TestTable", "Alias", null); //RSqlBuilder ParentRsb = RSqlBuilder.Select("PrizeID", "Prize",null); //RSqlBuilder rsb = RSqlBuilder.SubSelectWhere("*", "Prize", "Awards", "Alias", null, ParentRsb); //================End SubQuery============================================================ //================Begin Join============================================================ //RSqlBuilder JRsb = new RSqlBuilder(RAopEnum.Select.ToString(), "UserName", "TestTable","t"); List keys = new List (); //写法1 //string key1=TableNames.Awards.ToString()+".PrizeID"; //string key2=TableNames.Prize.ToString()+".PrizeID"; //写法2 //keys.Add(new OnKey("UserInfo.UserID", "UserInfo.UserID")); //keys.Add(new OnKey(TableNames.Awards.ToString() + ".PrizeID", TableNames.Prize.ToString() + ".PrizeID")); //keys.Add(new OnKey(TableNames.Awards.ToString() + "."+Awards.PrizeID.ToString(), TableNames.Prize.ToString() + "."+Prize.PrizeID.ToString())); //写法3 keys.Add(new OnKey(TableNames.UserInfo.ToString() + "." + UserInfo.AwardsID.ToString(), TableNames.Awards.ToString() + "." + Awards.AwardsID.ToString())); keys.Add(new OnKey(TableNames.UserInfo.ToString() + "." + UserInfo.BranchID.ToString(), TableNames.Branch.ToString() + "." + Branch.BranchID.ToString())); //RSqlBuilder不支持自连接 //RSqlBuilder rsb = RSqlBuilder.Join(new string[1] { TableNames.UserInfo.ToString() }, keys,list); //指定两个表名连接 //RSqlBuilder rsb=RSqlBuilder.Join(TableNames.Awards.ToString(), TableNames.Prize.ToString(), keys,list); //构造一个表数组进行连接 //RSqlBuilder rsb = RSqlBuilder.Join(new string[2] { TableNames.Awards.ToString(), TableNames.Prize.ToString() }, keys,list); RSqlBuilder rsb = RSqlBuilder.Join(new string[3] { TableNames.Awards.ToString(), TableNames.UserInfo.ToString(), TableNames.Branch.ToString() }, keys, list); //================End Join============================================================ //================Begin Top============================================================ //普通前几条数据查询 //RSqlBuilder rsb = RSqlBuilder.Select("*", "UserInfo", "Alias", null).Top(2); //连表的前几条数据查询 //RSqlBuilder rsb = RSqlBuilder.Join(new string[2] { TableNames.Awards.ToString(), TableNames.Prize.ToString() }, keys, null).Top(1); //子查询的前几条数据查询 //RSqlBuilder ParentRsb = RSqlBuilder.Select("PrizeID", "Prize",null); //RSqlBuilder rsb = RSqlBuilder.SubSelectWhere("*", "PrizeID", "Awards", "Alias", null, ParentRsb).Top(2);//where子查询 //RSqlBuilder rsb = RSqlBuilder.SubSelectForm("*", "Alias", null, ParentRsb).Top(2);//Form子查询 //================End Top============================================================ //================Begin OrderBy============================================================ //先Top或先OrderBy都没关系 //前10条的升序排序 //RSqlBuilder rsb = RSqlBuilder.Select("PrizeID", "Prize", null).Top(10).OrderByAsc(Prize.PrizeID); //连表的前几条升序排序 //RSqlBuilder rsb = RSqlBuilder.Join(new string[2] { TableNames.Awards.ToString(), TableNames.Prize.ToString() }, keys, null).Top(5).OrderByAsc(Awards.AwardsID);//最好加上表名作为前缀 //子查询的前几条数据降序排序 //RSqlBuilder ParentRsb = RSqlBuilder.Select("PrizeID", "Prize",null); //RSqlBuilder rsb = RSqlBuilder.SubSelectWhere("*", "PrizeID", "Awards", "Alias", null, ParentRsb).Top(3).OrderByDesc(Prize.PrizeID);//where子查询 //RSqlBuilder rsb = RSqlBuilder.SubSelectForm("*", "Alias", null, ParentRsb).Top(2).OrderByDesc(Prize.PrizeID);//Form子查询 //================End OrderBy============================================================ //注意点,子查询嵌套连表有一些限制 //1.允许将连表的数据(rsb)嵌入到子查询中,但必须先得到连表的JoinRsb,再在另外一个rsb实例中使用JoinRsb(其实就是一句话,子查询和连表不能链式编程) //2.没有实现将子查询数据用去连表操作 //================Begin 分页============================================================ //兼容数据库 //可扩展,更面向对象//RSqlBuilder rsb = RSqlBuilder.Select("PrizeID", "Prize", null).Page("*", "t", 1, 5, "PrizeID",null); //RSqlBuilder rsb = RSqlBuilder.Select("PrizeID", "Prize", null).Page(1, 5,"*", "t", "PrizeID"); //================End 分页============================================================ //================Begin Count============================================================ //RSqlBuilder rsb = RSqlBuilder.Select("PrizeID", "Prize", null).Page("*", "t", 1, 5, "PrizeID", null).Count(); //================End Count============================================================ //================Begin GroupBy============================================================ //================End GroupBy============================================================ //================Begin Distinct============================================================ //注意点: //1.distinct在分页前,不能distinct分页数据 //distinct只作用于内层 //不重复前10条的升序排序 //RSqlBuilder rsb = RSqlBuilder.Select("PrizeID", "Prize", null).Top(10).OrderByAsc(Prize.PrizeID).Distinct(); //连表的前几条升序排序 //RSqlBuilder rsb = RSqlBuilder.Join(new string[2] { TableNames.Awards.ToString(), TableNames.Prize.ToString() }, keys, null).Top(5).OrderByAsc(Awards.AwardsID).Distinct();//最好加上表名作为前缀 //子查询的前几条数据降序排序 //RSqlBuilder ParentRsb = RSqlBuilder.Select("PrizeID", "Prize", null); //RSqlBuilder rsb = RSqlBuilder.SubSelectWhere("*", "PrizeID", "Awards", "Alias", null, ParentRsb).Top(3).OrderByDesc(Prize.PrizeID).Distinct();//where子查询 //RSqlBuilder rsb = RSqlBuilder.SubSelectForm("*", "Alias", null, ParentRsb).Top(2).OrderByDesc(Prize.PrizeID);//Form子查询 //================End Distinct============================================================ //是否跳过aop,默认为false rp.SkipAop = false; if (rsb.innerRunnable != null) { return ""; } //获取rp运行结果 RRunnable run = rp.ExecuteQuerySqlBuilder(rsb); //RRunnable run = rp.ExecuteScalarSqlBuilder(rsb); rp.RClose(); //Result标识运行结果是否正常 if (run.Result == 1) { //获取运行结果的上下文 RContext context = run.getContext(); //通过上下文获取结果集(以集合形式返回) //List d = context.getDataSource (); //通过上下文获取结果集(以DataTable形式返回) DataTable dt = context.getDataSource2 (); int c = dt.Rows.Count; List > record = context.getDataSource(); //context = run2.getContext(); //通过上下文获取结果集(以字符串形式返回) //string value = context.getDataSource2 (); } else { //运行结果的操作信息 string Error = run.Meassage; //详细信息(json表示) string ErrorJsonString = run.ToString(); //信息数据 Dictionary dic = (Dictionary )run.Data; //.net framework异常内部信息 Exception ex = run.innerException; } string Result = "{\"Text\":\"Success\"}"; return Result; }
RSqlBuilder在这个版本还是存在很多不足以及问题,以后改动之后会再补充RSqlBuilder的说明。