MakeMsJoinSql.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Data;
  6. using System.Web;
  7. using Ant.Data;
  8. using System.Diagnostics;
  9. namespace Ant.ORM
  10. {
  11. public class MakeMsJoinSql : SqlQuery
  12. {
  13. public string SelectColumn = "";
  14. public string JoinTable = "";
  15. private static volatile MakeMsJoinSql instance = null;
  16. private static object lockHelper = new object();
  17. public StringPlus StrShowSql = new StringPlus("Select "); //组装外显的SQL语句
  18. public StringPlus StrSql = new StringPlus(); //组装SQL语句
  19. public SqlEntity sqlmod = new SqlEntity();
  20. public MakeMsJoinSql()
  21. {
  22. StrShowSql = new StringPlus("Select "); //组装外显的SQL语句
  23. StrSql = new StringPlus(); //组装SQL语句
  24. }
  25. #region 赋值为了组装SQL语句
  26. /// <summary>
  27. /// 查询外显字段
  28. /// </summary>
  29. /// <param name="colume"></param>
  30. /// <returns></returns>
  31. public SqlQuery Select(MakeShowFields colume)
  32. {
  33. sqlmod.FieldColumns = colume;
  34. return this;
  35. }
  36. /// <summary>
  37. /// 查询外显字段
  38. /// </summary>
  39. /// <param name="colume"></param>
  40. /// <returns></returns>
  41. public SqlQuery Select()
  42. {
  43. sqlmod.FieldColumns = null;
  44. return this;
  45. }
  46. /// <summary>
  47. /// Top条数
  48. /// </summary>
  49. /// <param name="num"></param>
  50. /// <returns></returns>
  51. public SqlQuery Top(int num)
  52. {
  53. sqlmod.StrTop = num;
  54. return this;
  55. }
  56. /// <summary>
  57. /// 分页方法
  58. /// </summary>
  59. /// <param name="pagesize"></param>
  60. /// <param name="pageno"></param>
  61. /// <returns></returns>
  62. public SqlQuery PageSize(int pagesize, int pageno)
  63. {
  64. sqlmod.PageSize = pagesize;
  65. sqlmod.PageNo = pageno;
  66. return this;
  67. }
  68. /// <summary>
  69. /// 查询主表
  70. /// </summary>
  71. /// <typeparam name="T"></typeparam>
  72. /// <param name="strasname"></param>
  73. /// <returns></returns>
  74. public SqlQuery From<T>(string strasname)
  75. {
  76. sqlmod.StrFrom = typeof(T).Name;
  77. sqlmod.StrAsName = strasname;
  78. return this;
  79. }
  80. /// <summary>
  81. /// 关联表
  82. /// </summary>
  83. /// <param name="jointable"></param>
  84. /// <returns></returns>
  85. public SqlQuery Join(MakeJoinTable jointable)
  86. {
  87. sqlmod.JoinTable = jointable;
  88. return this;
  89. }
  90. /// <summary>
  91. /// 查询条件
  92. /// </summary>
  93. /// <param name="where"></param>
  94. /// <returns></returns>
  95. public SqlQuery Where(MakeQueryWhere where)
  96. {
  97. sqlmod.QueryWhere = where;
  98. return this;
  99. }
  100. /// <summary>
  101. /// 排序条件
  102. /// </summary>
  103. /// <param name="where"></param>
  104. /// <returns></returns>
  105. public SqlQuery OrderBy(MakeOrderBy orderBy)
  106. {
  107. sqlmod.OrderBy = orderBy;
  108. foreach (var orderByModel in orderBy.OrderByList)
  109. {
  110. var tableAsName = GetTableAsName(orderByModel.TableName);
  111. foreach (var col in orderByModel.StrOrderBy)
  112. {
  113. sqlmod.StrOrderBy = sqlmod.StrOrderBy + " " + tableAsName + "." + col + " " + orderByModel.SortType + " ,";
  114. }
  115. }
  116. return this;
  117. }
  118. /// <summary>
  119. ///
  120. /// </summary>
  121. /// <param name="strlist"></param>
  122. /// <returns></returns>
  123. public SqlQuery Group(params string[] strlist)
  124. {
  125. return this;
  126. }
  127. /// <summary>
  128. /// 降序排序
  129. /// </summary>
  130. /// <param name="columns">The columns.</param>
  131. /// <returns></returns>
  132. public SqlQuery OrderDesc<T>(params string[] columns)
  133. {
  134. string tableAsName = GetTableAsName(typeof(T).Name);
  135. foreach (string column in columns)
  136. {
  137. sqlmod.StrOrderBy = sqlmod.StrOrderBy + " " + tableAsName + "." + column + " Desc ,";
  138. }
  139. return this;
  140. }
  141. /// <summary>
  142. /// 降序排序
  143. /// </summary>
  144. /// <param name="columns">The columns.</param>
  145. /// <returns></returns>
  146. public SqlQuery OrderAsc<T>(params string[] columns)
  147. {
  148. string tableAsName = GetTableAsName(typeof(T).Name);
  149. foreach (string column in columns)
  150. {
  151. sqlmod.StrOrderBy = sqlmod.StrOrderBy + " " + tableAsName + " . " + column + " asc ,";
  152. }
  153. return this;
  154. }
  155. #endregion
  156. /// <summary>
  157. /// 获取单个实体
  158. /// </summary>
  159. /// <typeparam name="T"></typeparam>
  160. /// <param name="db"></param>
  161. /// <returns></returns>
  162. public ResponseModel GetEnSingle<T>(SqlNote sqlNote, DataAccess db = null)
  163. {
  164. var enty = new ResponseModel();
  165. try
  166. {
  167. sqlmod.StrTop = 1;
  168. var dt = GetDtList(null, db);
  169. var mod = DataToModel.Dt2EnList<T>(dt.DataTable);
  170. enty.IsSuccess = true;
  171. enty.ResultModel = mod.FirstOrDefault();
  172. enty.StrSql = StrShowSql.ToString();
  173. return enty;
  174. }
  175. catch (Exception ex)
  176. {
  177. }
  178. return enty;
  179. }
  180. /// <summary>
  181. /// 获取列表
  182. /// </summary>
  183. /// <returns></returns>
  184. public ResponseModel GetDtList(SqlNote sqlNote, DataAccess db = null)
  185. {
  186. var response = new ResponseModel();
  187. try
  188. {
  189. if (sqlNote.IfNotNull())
  190. {
  191. if(sqlNote.NewSt.IsNull())
  192. {
  193. response.Message = "没有获取到方法的具体行号";
  194. return response;
  195. }
  196. if (sqlNote.Author.IsEmpty())
  197. {
  198. response.Message = "方法作者没有赋值";
  199. return response;
  200. }
  201. if(sqlNote.SqlDesc.IsEmpty())
  202. {
  203. response.Message = "方法的备注没有赋值";
  204. return response;
  205. }
  206. var dtlist = DataTableList(sqlNote, db);
  207. if (dtlist.IsHaveRows())
  208. {
  209. response.IsSuccess = true;
  210. response.ResultModel = dtlist;
  211. response.StrSql = StrShowSql.ToString();
  212. response.Message = "获取数据成功";
  213. }
  214. }
  215. }
  216. catch (Exception ex)
  217. {
  218. }
  219. return response;
  220. }
  221. /// <summary>
  222. /// 获取列表
  223. /// </summary>
  224. /// <typeparam name="T"></typeparam>
  225. /// <returns></returns>
  226. public ResponseModel GetEnList<T>(SqlNote newSt, DataAccess db = null)
  227. {
  228. var listmod = new ResponseModel();
  229. try
  230. {
  231. var dtlist = DataTableList(null, db);
  232. var modlist = DataToModel.Dt2EnList<T>(dtlist);
  233. listmod.ResultModel = modlist;
  234. listmod.IsSuccess = modlist.Count > 0;
  235. }
  236. catch (Exception ex)
  237. {
  238. }
  239. return listmod;
  240. }
  241. /// <summary>
  242. /// 分页方法
  243. /// </summary>
  244. /// <param name="pageno"></param>
  245. /// <param name="pagesize"></param>
  246. /// <param name="db"></param>
  247. /// <returns></returns>
  248. public ResponseModel GetPageSite(int pageno, int pagesize, SqlNote newSt, DataAccess db = null)
  249. {
  250. var response = new ResponseModel();
  251. try
  252. {
  253. sqlmod.PageSize = pagesize;
  254. sqlmod.PageNo = pageno;
  255. var dtt = PageSiteDatable(newSt,db);
  256. if (dtt.Rows.Count > 0)
  257. {
  258. response.IsSuccess = true;
  259. response.DataTable = dtt;
  260. response.Message = "查询DataTable返回成功";
  261. }
  262. }
  263. catch (Exception ex)
  264. {
  265. }
  266. return response;
  267. }
  268. #region 组装SQL语句
  269. /// <summary>
  270. /// 获取分页DataTable
  271. /// </summary>
  272. /// <param name="db"></param>
  273. /// <returns></returns>
  274. private DataTable PageSiteDatable(SqlNote newSt, DataAccess db)
  275. {
  276. string columnName; object columnValue; string tableName; string tableAsName = string.Empty; DbType dbtype; string overcolumnName;
  277. StrShowSql.Append("SELECT * FROM (SELECT ROW_NUMBER() OVER (");
  278. if (string.IsNullOrEmpty(sqlmod.StrOrderBy))
  279. {
  280. StrShowSql.Append(" order by ");
  281. StrShowSql.Append(sqlmod.StrAsName + "." + sqlmod.StrOrderBy);
  282. }
  283. else
  284. {
  285. //主键
  286. StrShowSql.Append(" order by ");
  287. }
  288. StrShowSql.Append(") AS rowNumber,");
  289. var showfiled = sqlmod.FieldColumns;
  290. #region 拼接显示字段
  291. if (showfiled.IsNull())
  292. {
  293. StrShowSql.Append(" * ");
  294. }
  295. else
  296. {
  297. foreach (FieldColumnsList fieldList in showfiled.Values)
  298. {
  299. tableName = fieldList.TableName;
  300. tableAsName = GetTableAsName(tableName);
  301. foreach (FieldColumns feild in fieldList.FieldList)
  302. {
  303. if (!feild.FieldAsName.IsEmpty())
  304. StrShowSql.Append(tableAsName + "." + feild.FieldColumn + " as " + feild.FieldAsName + ",");
  305. else
  306. StrShowSql.Append(tableAsName + "." + feild.FieldColumn + ",");
  307. StrShowSql.AppendLine();
  308. }
  309. }
  310. }
  311. #endregion
  312. StrShowSql.DelLastComma();
  313. StrShowSql.Append(" from ");
  314. StrShowSql.Append(sqlmod.StrFrom + " as " + sqlmod.StrAsName + " with (nolock) ");
  315. #region 拼接关联表
  316. foreach (JoinOnTableNode jion in sqlmod.JoinTable.RootList)
  317. {
  318. string tableAsName1 = GetTableAsName(jion.TableName); string tableAsName2 = GetTableAsName(jion.NTableName);
  319. StrShowSql.Append(JoinSql.GetJoinTypeValue(jion.JoinType) + " " + jion.NTableName + " as " + jion.NTableAsName);
  320. StrShowSql.Append(" " + tableAsName1 + "." + jion.JoinOn1 + "=" + tableAsName2 + "." + jion.JoinOn2);
  321. StrShowSql.AppendLine();
  322. }
  323. #endregion
  324. StrShowSql.Append(" where 1=1 ");
  325. StrSql.Append(StrShowSql);//把外显示SQL组装带到参数的SQL中去
  326. MakeQueryWhere where = sqlmod.QueryWhere;
  327. #region 拼接查询条件
  328. if (where.IfNotNull())
  329. {
  330. foreach (QueryWhereList queryList in where.QueryList.Values)
  331. {
  332. foreach (TableColumn col in queryList.QueryList)
  333. {
  334. columnName = col.ColumnName;
  335. overcolumnName = (col.OverColumnName.IsEmpty()) ? columnName : col.OverColumnName;
  336. columnValue = col.ColumnValue;
  337. dbtype = col.ColumnType;
  338. tableName = col.TableName;
  339. tableAsName = GetTableAsName(tableName) + "." + columnName;
  340. if (col.Operatstr==Operator.Like)
  341. {
  342. StrShowSql.Append(queryList.WhereStr + tableAsName +
  343. QueryOperator.GetOperator(col.Operatstr) + " %" +
  344. GetNativeType(dbtype, columnValue) + "% ");
  345. StrSql.Append(queryList.WhereStr + tableAsName + QueryOperator.GetOperator(col.Operatstr) +
  346. "@" + overcolumnName + " ESCAPE '!' ");
  347. var parameter = new QueryParameter();
  348. parameter.ParameterName = "@" + overcolumnName;
  349. parameter.Value = string.Format("%{0}%", GetEscape(columnValue.ToString()));
  350. parameter.DbType = dbtype;
  351. sqlmod.Parameters.Add(parameter);
  352. }
  353. else
  354. {
  355. StrShowSql.Append(queryList.WhereStr + tableAsName + QueryOperator.GetOperator(col.Operatstr) + GetNativeType(dbtype, columnValue));
  356. StrSql.Append(queryList.WhereStr + tableAsName + QueryOperator.GetOperator(col.Operatstr) + "@" +
  357. overcolumnName);
  358. var parameter = new QueryParameter();
  359. parameter.ParameterName = "@" + overcolumnName;
  360. parameter.Value = columnValue;
  361. parameter.DbType = dbtype;
  362. sqlmod.Parameters.Add(parameter);
  363. }
  364. }
  365. }
  366. }
  367. #endregion
  368. StrSql.AppendFormat(") AS sp WHERE rowNumber BETWEEN {0} and {1} ", (sqlmod.PageNo + 1), (sqlmod.PageNo + sqlmod.PageSize));
  369. if (db.IsNull())
  370. db = DataAccessFactory.GetWriteDataDefault;
  371. StrSql.Append(GetSqlComments(newSt));
  372. IDataReader rdr = db.ExecuteDataReader(StrSql.ToString(), sqlmod.Parameters);
  373. DataTable dtt = DataToModel.Dr2Dt(rdr);
  374. return dtt;
  375. }
  376. /// <summary>
  377. /// 获取DataTableList
  378. /// </summary>
  379. /// <param name="db"></param>
  380. /// <returns></returns>
  381. private DataTable DataTableList(SqlNote newSt, DataAccess db)
  382. {
  383. string columnName; object columnValue; string tableName; string tableAsName = string.Empty; DbType dbtype;
  384. string overcolumnName;
  385. if (sqlmod.StrTop > 0)
  386. StrShowSql.AppendFormat(" top {0} ", sqlmod.StrTop);
  387. #region 拼接显示字段
  388. var showfiled = sqlmod.FieldColumns;
  389. if (showfiled.IsNull())
  390. {
  391. StrShowSql.Append(" * ");
  392. }
  393. else
  394. {
  395. foreach (FieldColumnsList fieldList in showfiled.Values)
  396. {
  397. tableAsName = GetTableAsName(fieldList.TableName);
  398. foreach (FieldColumns feild in fieldList.FieldList)
  399. {
  400. if (!feild.FieldAsName.IsEmpty())
  401. StrShowSql.Append(tableAsName + "." + feild.FieldColumn + " as " + feild.FieldAsName + ",");
  402. else
  403. StrShowSql.Append(tableAsName + "." + feild.FieldColumn + ",");
  404. }
  405. StrShowSql.AppendLine();
  406. }
  407. }
  408. #endregion
  409. StrShowSql.DelLastComma();
  410. StrShowSql.Append(" from " + sqlmod.StrFrom + " as " + sqlmod.StrAsName + " with (nolock) ");
  411. StrShowSql.AppendLine();
  412. #region 拼接关联表
  413. foreach (JoinOnTableNode jion in sqlmod.JoinTable.RootList)
  414. {
  415. string tableAsName1 = GetTableAsName(jion.TableName); string tableAsName2 = GetTableAsName(jion.NTableName);
  416. StrShowSql.Append(JoinSql.GetJoinTypeValue(jion.JoinType) + " " + jion.NTableName + " as " + jion.NTableAsName + " with (nolock) on ");
  417. StrShowSql.Append(tableAsName1 + "." + jion.JoinOn1 + "=" + tableAsName2 + "." + jion.JoinOn2);
  418. StrShowSql.AppendLine();
  419. }
  420. #endregion
  421. StrShowSql.Append(" where 1=1 ");
  422. StrSql.Append(StrShowSql);//把外显示SQL组装带到参数的SQL中去
  423. #region 拼接查询条件
  424. MakeQueryWhere where = sqlmod.QueryWhere;
  425. if (where.IfNotNull())
  426. {
  427. foreach (QueryWhereList queryList in where.QueryList.Values)
  428. {
  429. if(queryList.QueryList.Count>0)
  430. {
  431. StrSql.Append("(");
  432. StrShowSql.Append("(");
  433. }
  434. foreach (TableColumn col in queryList.QueryList)
  435. {
  436. columnName = col.ColumnName;
  437. overcolumnName = (col.OverColumnName.IsEmpty()) ? columnName : col.OverColumnName;
  438. columnValue = col.ColumnValue;
  439. dbtype = col.ColumnType;
  440. tableName = col.TableName;
  441. tableAsName = GetTableAsName(tableName) + "." + columnName;
  442. StrShowSql.Append(tableAsName + QueryOperator.GetOperator(col.Operatstr) + GetNativeType(dbtype, columnValue) + queryList.WhereStr);
  443. StrSql.Append(tableAsName + QueryOperator.GetOperator(col.Operatstr) + "@" + overcolumnName + queryList.WhereStr);
  444. var parameter = new QueryParameter();
  445. parameter.ParameterName = "@" + overcolumnName;
  446. parameter.Value = columnValue;
  447. parameter.DbType = dbtype;
  448. sqlmod.Parameters.Add(parameter);
  449. }
  450. if(queryList.QueryList.Count>0)
  451. {
  452. StrShowSql.DelLastChar(" and ");
  453. StrShowSql.DelLastChar(" or ");
  454. StrSql.DelLastChar(" and ");
  455. StrSql.DelLastChar(" or ");
  456. StrSql.Append(")");
  457. StrShowSql.Append(")");
  458. }
  459. }
  460. }
  461. #endregion
  462. if (sqlmod.StrOrderBy.IfNotNull())
  463. {
  464. if (sqlmod.StrOrderBy.EndsWith(","))
  465. sqlmod.StrOrderBy = sqlmod.StrOrderBy.TrimEnd(',');
  466. StrShowSql.Append(" order by " + sqlmod.StrOrderBy);
  467. StrSql.Append(" order by " + sqlmod.StrOrderBy);
  468. }
  469. if (db.IsNull())
  470. db = DataAccessFactory.GetWriteDataDefault;
  471. StrSql.Append(GetSqlComments(newSt));
  472. IDataReader rdr = db.ExecuteDataReader(StrSql.ToString(), sqlmod.Parameters);
  473. DataTable dtt = DataToModel.Dr2Dt(rdr);
  474. return dtt;
  475. }
  476. #endregion
  477. #region 返回sql注释
  478. /// <summary>
  479. /// 返回sql注释
  480. /// </summary>
  481. /// <param name="newSt">调用方法new StackTrace(true)</param>
  482. /// <param name="author">sql作者</param>
  483. /// <param name="sqlDesc">sql说明</param>
  484. /// <returns></returns>
  485. /// <remarks>
  486. /// added by 季健国 at 2015-3-7
  487. /// </remarks>
  488. public static string GetSqlComments(SqlNote sqlNote)
  489. {
  490. try
  491. {
  492. StackFrame stackFrame = sqlNote.NewSt.GetFrame(0);
  493. StringBuilder commetBuilder = new StringBuilder();
  494. commetBuilder.AppendFormat("/*项目名称:{0}/作者:{1}/备注:{2}/文件:///{3}/方法:{4}/行号:{5}*/","某某项目", sqlNote.Author, sqlNote.SqlDesc, stackFrame.GetFileName(), stackFrame.GetMethod().Name, stackFrame.GetFileLineNumber());
  495. return commetBuilder.ToString();
  496. }
  497. catch
  498. {
  499. //默认许可按此处理
  500. return "";
  501. }
  502. }
  503. #endregion
  504. /// <summary>
  505. /// 获取别名
  506. /// </summary>
  507. /// <param name="tablename"></param>
  508. /// <returns></returns>
  509. private string GetTableAsName(string tablename)
  510. {
  511. string tableasname;
  512. if (tablename == sqlmod.StrFrom)
  513. {
  514. tableasname = sqlmod.StrAsName;
  515. if (tableasname.IsEmpty())
  516. tableasname = sqlmod.StrFrom;
  517. }
  518. else
  519. {
  520. var mod = sqlmod.JoinTable.RootList.Find(p => p.NTableName.Equals(tablename));
  521. tableasname = mod.NTableAsName;
  522. if (tableasname.IsEmpty())
  523. tableasname = mod.TableName;
  524. }
  525. return tableasname;
  526. }
  527. /// <summary>
  528. /// 通配符转换
  529. /// </summary>
  530. /// <param name="str"></param>
  531. /// <returns></returns>
  532. protected static string GetEscape(string str)
  533. {
  534. return str.Replace("!", "!!").Replace("%", "!%").Replace("_", "!_");
  535. }
  536. /// <summary>
  537. /// Gets the type of the native.
  538. /// </summary>
  539. /// <param name="dbType">Type of the db.</param>
  540. /// <returns></returns>
  541. private object GetNativeType(DbType dbType, object obj)
  542. {
  543. switch (dbType)
  544. {
  545. case DbType.AnsiString:
  546. case DbType.Object:
  547. case DbType.String:
  548. case DbType.AnsiStringFixedLength:
  549. case DbType.StringFixedLength:
  550. return "'" + obj + "'";
  551. case DbType.Binary:
  552. case DbType.Byte:
  553. case DbType.SByte:
  554. return "'" + obj + "'";
  555. case DbType.Boolean:
  556. return obj;
  557. case DbType.Currency:
  558. return "money";
  559. case DbType.Date:
  560. case DbType.DateTime:
  561. case DbType.Time:
  562. return "'" + obj + "'";
  563. case DbType.Decimal:
  564. return obj;
  565. case DbType.Double:
  566. return obj;
  567. case DbType.Guid:
  568. return "'" + obj + "'";
  569. case DbType.Int16:
  570. case DbType.Int32:
  571. case DbType.UInt16:
  572. case DbType.UInt32:
  573. return obj;
  574. case DbType.Int64:
  575. case DbType.UInt64:
  576. return obj;
  577. case DbType.Single:
  578. return "'" + obj + "'";
  579. case DbType.VarNumeric:
  580. return obj;
  581. case DbType.Xml:
  582. return "'" + obj + "'";
  583. }
  584. return obj;
  585. }
  586. }
  587. }