.net6.0 webapi demo

CreateCodeFileHelper.cs 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. using EFCore.Sharding;
  2. using Microsoft.Data.SqlClient;
  3. using Microsoft.Extensions.Hosting;
  4. using MySqlConnector;
  5. using Npgsql;
  6. using Oracle.ManagedDataAccess.Client;
  7. using System.Data;
  8. using System.Data.Common;
  9. using System.Net;
  10. using System.Text;
  11. namespace Net6Demo_Api.Util
  12. {
  13. public class CreateCodeFileHelper : ITransientDependency
  14. {
  15. private readonly IDbAccessor _db;
  16. private readonly IHostEnvironment _env;
  17. private readonly DbProviderFactory _factory;
  18. private string _key;
  19. public CreateCodeFileHelper(IDbAccessor db, IHostEnvironment env)
  20. {
  21. _db = db;
  22. _env = env;
  23. switch (db.DbType)
  24. {
  25. case DatabaseType.SqlServer: _factory = SqlClientFactory.Instance; break;
  26. case DatabaseType.MySql: _factory = MySqlConnectorFactory.Instance; break;
  27. case DatabaseType.PostgreSql: _factory = NpgsqlFactory.Instance; break;
  28. case DatabaseType.Oracle: _factory = OracleClientFactory.Instance; break;
  29. default: throw new Exception("此数据库不支持!");
  30. }
  31. }
  32. private int _isCover = 0;
  33. /// <summary>
  34. /// 生成代码文件
  35. /// </summary>
  36. /// <param name="tableName"></param>
  37. public void CreateCodeFile(string tableName, string controllerName, string moduleName, int isOnlyEntity = 0, int isCover = 0)
  38. {
  39. _isCover = isCover;
  40. var list = GetDataTableWithSql(DbTableSqlDic[_db.DbType]).ToJson().ToObject<List<TableInfo>>();
  41. if (!string.IsNullOrEmpty(tableName)) list = list.Where(p => p.Name.ToLower() == tableName.ToLower()).ToList();
  42. foreach (var item in list)
  43. {
  44. CreateEntityFile(item.Name, item.Description, controllerName, moduleName);
  45. if (isOnlyEntity == 0)
  46. {
  47. CreateBusinessFile(item.Name, controllerName, moduleName);
  48. CreateControllerFile(item.Name, controllerName, moduleName);
  49. }
  50. }
  51. }
  52. /// <summary>
  53. /// 生成实体文件
  54. /// </summary>
  55. public void CreateEntityFile(string tableName, string tableDescription, string controllerName, string moduleName)
  56. {
  57. moduleName = string.IsNullOrEmpty(moduleName) ? "" : moduleName + "\\";
  58. string path = Directory.GetParent(_env.ContentRootPath).Parent.FullName;
  59. string pname = _env.ApplicationName;
  60. var dbtype = _db.DbType;
  61. var columns = GetDataTableWithSql(DbTableColumnSqlDic[dbtype], new Dictionary<string, string>() { { "@tablename", tableName } }).ToJson().ToObject<List<TableColumn>>();
  62. int index = 0;
  63. string properties = string.Empty;
  64. string inputproperties = string.Empty;
  65. string viewproperties = string.Empty;
  66. foreach (var column in columns)
  67. {
  68. string key = string.Empty;
  69. if (column.IsKey)
  70. {
  71. key = $@"
  72. [Key, Column(Order = {index + 1})]";
  73. _key = column.Name;
  74. }
  75. Type type = DbTypeToCsharpType(column.Type);
  76. //string isNullable = column.IsNullable && type.IsValueType ? "?" : "";
  77. string isNullable = column.IsNullable ? "?" : "";
  78. string description = string.IsNullOrEmpty(column.Description) ? column.Name : column.Description;
  79. properties += $@"
  80. /// <summary>{description}</summary>{key}
  81. public {type.Name}{isNullable} {column.Name} {{ get; set; }}
  82. ";
  83. inputproperties += $@"
  84. /// <summary>{description}</summary>
  85. public {type.Name}{isNullable} {(column.Name.StartsWith("F_") ? column.Name.Substring(2) : column.Name)} {{ get; set; }}
  86. ";
  87. viewproperties += $@"
  88. /// <summary>{description}</summary>
  89. public {type.Name}{isNullable} {(column.Name.StartsWith("F_") ? column.Name.Substring(2) : column.Name)} {{ get; set; }}
  90. ";
  91. index++;
  92. }
  93. string entityContent = $@"
  94. using System.ComponentModel.DataAnnotations;
  95. using System.ComponentModel.DataAnnotations.Schema;
  96. namespace {pname}.Entity
  97. {{
  98. /// <summary>
  99. /// {tableDescription}
  100. /// </summary>
  101. [Table(""{tableName}"")]
  102. public class {tableName}
  103. {{
  104. {properties}
  105. }}
  106. }}";
  107. CreateFile($@"{path}\{pname}.Entity\DataBase\{moduleName}\{tableName}.cs", entityContent);
  108. string inputEntityContent = $@"
  109. using {pname}.Util;
  110. namespace {pname}.Entity
  111. {{
  112. /// <summary>
  113. /// {tableDescription}
  114. /// </summary>
  115. [Map(typeof({tableName}))]
  116. public class {controllerName}Input
  117. {{
  118. {inputproperties}
  119. }}
  120. }}";
  121. CreateFile($@"{path}\{pname}.Entity\Input\{moduleName}\{controllerName}Input.cs", inputEntityContent);
  122. string viewEntityContent = $@"
  123. using {pname}.Util;
  124. namespace {pname}.Entity
  125. {{
  126. /// <summary>
  127. /// {tableDescription}
  128. /// </summary>
  129. [Map(typeof({tableName}))]
  130. public class {controllerName}View
  131. {{
  132. {viewproperties}
  133. }}
  134. }}";
  135. CreateFile($@"{path}\{pname}.Entity\View\{moduleName}\{controllerName}View.cs", viewEntityContent);
  136. //数据库类型转C#类型
  137. Type DbTypeToCsharpType(string dbTypeStr)
  138. {
  139. string _dbTypeStr = dbTypeStr.ToLower();
  140. Type type = null;
  141. if (DbTypeDic[dbtype].ContainsKey(_dbTypeStr))
  142. type = DbTypeDic[dbtype][_dbTypeStr];
  143. else
  144. type = typeof(string);
  145. return type;
  146. }
  147. }
  148. /// <summary>
  149. /// 生成控制器文件
  150. /// </summary>
  151. /// <param name="tableName"></param>
  152. /// <param name="controllerName"></param>
  153. /// <param name="moduleName"></param>
  154. public void CreateControllerFile(string tableName, string controllerName, string moduleName)
  155. {
  156. moduleName = string.IsNullOrEmpty(moduleName) ? "" : moduleName + "\\";
  157. string path = _env.ContentRootPath + "\\Controllers\\" + moduleName;
  158. string pname = _env.ApplicationName;
  159. string controllerContent = $@"
  160. using AutoMapper;
  161. using LinqKit;
  162. using Microsoft.AspNetCore.Http;
  163. using Microsoft.AspNetCore.Mvc;
  164. using Microsoft.EntityFrameworkCore;
  165. using {pname}.Entity;
  166. using {pname}.IBusiness;
  167. namespace {pname}.Controllers
  168. {{
  169. public class {controllerName}Controller : BaseController
  170. {{
  171. private readonly I{controllerName}Business _{controllerName}Bus;
  172. private readonly IMapper _mapper;
  173. public {controllerName}Controller(I{controllerName}Business {controllerName}Bus, IMapper mapper)
  174. {{
  175. _{controllerName}Bus = {controllerName}Bus;
  176. _mapper = mapper;
  177. }}
  178. /// <summary>
  179. /// 获取分页列表
  180. /// </summary>
  181. /// <param name=""input""></param>
  182. /// <returns></returns>
  183. [HttpPost]
  184. public async Task<ActionResult> GetDataListPage(PageInput<{controllerName}Input> input)
  185. {{
  186. var q = PredicateBuilder.New<{tableName}>(true);
  187. var data = await _{controllerName}Bus.GetListPageAsync(input, q, p => p.OrderByDescending(q => q.{_key}));
  188. return Success(""成功"", _mapper.Map<List<{controllerName}View>>(data.Item1), data.Item2);
  189. }}
  190. /// <summary>
  191. /// 获取单个
  192. /// </summary>
  193. /// <param name=""id"">主键ID</param>
  194. /// <returns></returns>
  195. [HttpGet]
  196. public async Task<ActionResult> GetData(int id)
  197. {{
  198. var data = await _{controllerName}Bus.GetEntityAsync(id);
  199. if (data != null) return Success(""成功"", _mapper.Map<{controllerName}View>(data));
  200. else return Error(""获取失败"");
  201. }}
  202. /// <summary>
  203. /// 新增
  204. /// </summary>
  205. /// <param name=""input"" ></param>
  206. /// <returns></returns>
  207. [HttpPost]
  208. public async Task<ActionResult> AddData({controllerName}Input input)
  209. {{
  210. {tableName} model = _mapper.Map<{tableName}>(input);
  211. int result = await _{controllerName}Bus.InsertAsync(model);
  212. if (result > 0) return Success(""成功"");
  213. else return Error(""失败"");
  214. }}
  215. /// <summary>
  216. /// 编辑
  217. /// </summary>
  218. /// <param name=""input"" ></param>
  219. /// <returns></returns>
  220. [HttpPost]
  221. public async Task<ActionResult> EditData({controllerName}Input input)
  222. {{
  223. int result = 0;
  224. var oldData = await _{controllerName}Bus.GetEntityAsync(input.{(_key.StartsWith("F_") ? _key.Substring(2) : _key)});
  225. if (oldData != null)
  226. {{
  227. _mapper.Map(input, oldData);
  228. result = await _{controllerName}Bus.UpdateAsync(oldData);
  229. }}
  230. if (result > 0) return Success(""成功"");
  231. else return Error(""失败"");
  232. }}
  233. /// <summary>
  234. /// 删除
  235. /// </summary>
  236. /// <param name=""ids"" ></param>
  237. /// <returns></returns>
  238. [HttpPost]
  239. public async Task<ActionResult> DeleteData(List<string> ids)
  240. {{
  241. if (await _{controllerName}Bus.DeleteAsync(ids) > 0) return Success(""删除成功"");
  242. else return Error(""删除失败"");
  243. }}
  244. }}
  245. }}
  246. ";
  247. CreateFile($@"{path}\{controllerName}Controller.cs", controllerContent);
  248. }
  249. /// <summary>
  250. /// 生成业务文件
  251. /// </summary>
  252. /// <param name="tableName"></param>
  253. /// <param name="controllerName"></param>
  254. /// <param name="moduleName"></param>
  255. public void CreateBusinessFile(string tableName, string controllerName, string moduleName)
  256. {
  257. moduleName = string.IsNullOrEmpty(moduleName) ? "" : moduleName + "\\";
  258. string path = Directory.GetParent(_env.ContentRootPath).Parent.FullName;
  259. string pname = _env.ApplicationName;
  260. string iBusinessContent = $@"
  261. using {pname}.Entity;
  262. namespace {pname}.IBusiness
  263. {{
  264. public interface I{controllerName}Business : IBaseBusiness<{tableName}>
  265. {{
  266. }}
  267. }}
  268. ";
  269. CreateFile($@"{path}\{pname}.IBusiness\{moduleName}I{controllerName}Business.cs", iBusinessContent);
  270. string businessContent = $@"
  271. using EFCore.Sharding;
  272. using Microsoft.Extensions.Caching.Distributed;
  273. using {pname}.Entity;
  274. using {pname}.IBusiness;
  275. using {pname}.Util;
  276. namespace {pname}.Business
  277. {{
  278. public class {controllerName}Business : BaseBusiness<{tableName}>, I{controllerName}Business, ITransientDependency
  279. {{
  280. public {controllerName}Business(IDbAccessor db, IDistributedCache cache) : base(db, cache, false)
  281. {{
  282. }}
  283. }}
  284. }}
  285. ";
  286. CreateFile($@"{path}\{pname}.Business\{moduleName}{controllerName}Business.cs", businessContent);
  287. }
  288. /// <summary>
  289. /// 创建文件
  290. /// </summary>
  291. /// <param name="filepath"></param>
  292. /// <param name="content"></param>
  293. private void CreateFile(string filepath, string content)
  294. {
  295. string path = filepath.Substring(0, filepath.LastIndexOf("\\"));
  296. if (!Directory.Exists(path)) Directory.CreateDirectory(path);
  297. if (File.Exists(filepath) && _isCover == 1) File.Delete(filepath);
  298. if (!File.Exists(filepath))
  299. {
  300. FileInfo file = new FileInfo(filepath);
  301. using (FileStream stream = file.Create())
  302. {
  303. using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8))
  304. {
  305. writer.Write(content);
  306. writer.Flush();
  307. }
  308. }
  309. }
  310. }
  311. /// <summary>
  312. /// 根据sql获取DataTable
  313. /// </summary>
  314. /// <param name="sql"></param>
  315. /// <param name="parameters"></param>
  316. /// <returns></returns>
  317. private DataTable GetDataTableWithSql(string sql, Dictionary<string, string> paras = null)
  318. {
  319. using (DbConnection conn = _factory.CreateConnection())
  320. {
  321. conn.ConnectionString = _db.ConnectionString;
  322. if (conn.State != ConnectionState.Open)
  323. {
  324. conn.Open();
  325. }
  326. using (DbCommand cmd = conn.CreateCommand())
  327. {
  328. cmd.Connection = conn;
  329. cmd.CommandText = sql;
  330. if (paras != null)
  331. {
  332. foreach (KeyValuePair<string, string> kvp in paras)
  333. {
  334. switch (_db.DbType)
  335. {
  336. case DatabaseType.SqlServer: cmd.Parameters.Add(new SqlParameter(kvp.Key, kvp.Value)); break;
  337. case DatabaseType.MySql: cmd.Parameters.Add(new MySqlParameter(kvp.Key, kvp.Value)); break;
  338. case DatabaseType.PostgreSql: cmd.Parameters.Add(new NpgsqlParameter(kvp.Key, kvp.Value)); break;
  339. case DatabaseType.Oracle: cmd.Parameters.Add(new OracleParameter(kvp.Key, kvp.Value)); break;
  340. }
  341. }
  342. }
  343. DbDataAdapter adapter = _factory.CreateDataAdapter();
  344. adapter.SelectCommand = cmd;
  345. DataSet table = new DataSet();
  346. adapter.Fill(table);
  347. cmd.Parameters.Clear();
  348. return table.Tables[0];
  349. }
  350. }
  351. }
  352. /// <summary>
  353. /// 数据库类型和C#类型字典
  354. /// </summary>
  355. private Dictionary<DatabaseType, Dictionary<string, Type>> DbTypeDic = new Dictionary<DatabaseType, Dictionary<string, Type>>()
  356. {
  357. { DatabaseType.SqlServer,new Dictionary<string, Type>()
  358. {
  359. { "int", typeof(Int32) },
  360. { "text", typeof(string) },
  361. { "bigint", typeof(Int64) },
  362. { "binary", typeof(byte[]) },
  363. { "bit", typeof(bool) },
  364. { "char", typeof(string) },
  365. { "date", typeof(DateTime) },
  366. { "datetime", typeof(DateTime) },
  367. { "datetime2", typeof(DateTime) },
  368. { "datetimeoffset", typeof(DateTimeOffset) },
  369. { "decimal", typeof(decimal) },
  370. { "float", typeof(double) },
  371. { "image", typeof(byte[]) },
  372. { "money", typeof(decimal) },
  373. { "nchar", typeof(string) },
  374. { "ntext", typeof(string) },
  375. { "numeric", typeof(decimal) },
  376. { "nvarchar", typeof(string) },
  377. { "real", typeof(Single) },
  378. { "smalldatetime", typeof(DateTime) },
  379. { "smallint", typeof(Int16) },
  380. { "smallmoney", typeof(decimal) },
  381. { "time", typeof(TimeSpan) },
  382. { "timestamp", typeof(DateTime) },
  383. { "tinyint", typeof(byte) },
  384. { "varbinary", typeof(byte[]) },
  385. { "varchar", typeof(string) },
  386. { "variant", typeof(object) },
  387. { "uniqueidentifier", typeof(Guid) }
  388. }
  389. },
  390. { DatabaseType.MySql,new Dictionary<string, Type>()
  391. {
  392. { "bool",typeof(bool)},
  393. { "boolean",typeof(bool)},
  394. { "bit(1)",typeof(bool)},
  395. { "binary",typeof(byte[])},
  396. { "varbinary",typeof(byte[])},
  397. { "blob",typeof(byte[])},
  398. { "longblob",typeof(byte[])},
  399. { "date",typeof(DateTime)},
  400. { "datetime",typeof(DateTime)},
  401. { "timestamp",typeof(DateTime)},
  402. { "datetimeoffset", typeof(DateTimeOffset) },
  403. { "time", typeof(TimeSpan) },
  404. { "double",typeof(double)},
  405. { "smallint",typeof(Int16)},
  406. { "int",typeof(Int32)},
  407. { "bigint",typeof(Int64)},
  408. { "tinyint",typeof(bool)},
  409. { "float",typeof(float)},
  410. { "decimal",typeof(decimal)},
  411. { "numeric",typeof(decimal)},
  412. { "char",typeof(string)},
  413. { "nchar",typeof(string)},
  414. { "varchar",typeof(string)},
  415. { "nvarchar",typeof(string)},
  416. { "text",typeof(string)},
  417. { "longtext",typeof(string)}
  418. }
  419. },
  420. { DatabaseType.PostgreSql,new Dictionary<string, Type>()
  421. {
  422. { "bool", typeof(bool) },
  423. { "boolean",typeof(bool)},
  424. { "int2", typeof(Int16) },
  425. { "smallint", typeof(Int16) },
  426. { "int4", typeof(Int32) },
  427. { "bigint", typeof(Int64) },
  428. { "int8", typeof(Int64) },
  429. { "integer", typeof(Int32) },
  430. { "float4", typeof(float) },
  431. { "float8", typeof(decimal) },
  432. { "decimal", typeof(decimal) },
  433. { "numeric", typeof(decimal) },
  434. { "money", typeof(decimal) },
  435. { "text", typeof(string) },
  436. { "varchar", typeof(string) },
  437. { "bpchar", typeof(string) },
  438. { "citext", typeof(string) },
  439. { "json", typeof(string) },
  440. { "jsonb", typeof(string) },
  441. { "xml", typeof(string) },
  442. { "bit(1)", typeof(bool) },
  443. { "uuid", typeof(Guid) },
  444. { "inet", typeof(IPAddress) },
  445. { "date", typeof(DateTime) },
  446. { "interval", typeof(TimeSpan) },
  447. { "timestamp", typeof(DateTime) },
  448. { "timestamptz", typeof(DateTime) },
  449. { "time", typeof(TimeSpan) },
  450. { "timetz", typeof(DateTimeOffset) },
  451. { "bytea", typeof(byte[]) },
  452. { "oid", typeof(uint) },
  453. { "xid", typeof(uint) },
  454. { "cid", typeof(uint) },
  455. { "name", typeof(string) }
  456. }
  457. },
  458. { DatabaseType.Oracle,new Dictionary<string, Type>()
  459. {
  460. { "boolean",typeof(bool)},
  461. { "bfile", typeof(byte[]) },
  462. { "blob", typeof(byte[]) },
  463. { "char", typeof(string) },
  464. { "clob", typeof(string) },
  465. { "date", typeof(DateTime) },
  466. { "float", typeof(decimal) },
  467. { "integer", typeof(decimal) },
  468. { "long", typeof(string) },
  469. { "long raw", typeof(string[]) },
  470. { "nchar", typeof(string) },
  471. { "nclob", typeof(string) },
  472. { "number", typeof(decimal) },
  473. { "nvarchar2", typeof(string) },
  474. { "raw", typeof(byte[]) },
  475. { "rowid", typeof(string) },
  476. { "timestamp", typeof(DateTime) },
  477. { "unsigned integer", typeof(decimal) },
  478. { "varchar2", typeof(string) }
  479. }
  480. },
  481. { DatabaseType.SQLite,new Dictionary<string, Type>()
  482. {
  483. { "tinyint", typeof(byte) },
  484. { "bool", typeof(bool) },
  485. { "boolean",typeof(bool)},
  486. { "int16", typeof(Int16) },
  487. { "smallint", typeof(Int16) },
  488. { "int32", typeof(Int32) },
  489. { "int", typeof(Int32) },
  490. { "int64", typeof(Int64) },
  491. { "integer", typeof(Int64) },
  492. { "text", typeof(string) },
  493. { "bigint", typeof(Int64) },
  494. { "real", typeof(double) },
  495. { "numeric", typeof(decimal) },
  496. { "decimal", typeof(decimal) },
  497. { "money", typeof(decimal) },
  498. { "currency", typeof(decimal) },
  499. { "date", typeof(DateTime) },
  500. { "smalldate", typeof(DateTime) },
  501. { "datetime", typeof(DateTime) },
  502. { "time", typeof(TimeSpan) },
  503. { "ntext", typeof(string) },
  504. { "char", typeof(string) },
  505. { "nchar", typeof(string) },
  506. { "varchar", typeof(string) },
  507. { "nvarchar", typeof(string) },
  508. { "string", typeof(string) },
  509. { "binary", typeof(byte[]) },
  510. { "blob", typeof(byte[]) },
  511. { "varbinary", typeof(byte[]) },
  512. { "image", typeof(byte[]) },
  513. { "general", typeof(byte[]) },
  514. { "datetimeoffset", typeof(DateTimeOffset) },
  515. { "guid", typeof(Guid) }
  516. }
  517. }
  518. };
  519. /// <summary>
  520. /// 数据库类型表sql字典
  521. /// </summary>
  522. private Dictionary<DatabaseType, string> DbTableSqlDic = new Dictionary<DatabaseType, string>()
  523. {
  524. { DatabaseType.SqlServer,
  525. "select [Name] = a.name, [Description] = g.value from sys.tables a left join sys.extended_properties g on (a.object_id = g.major_id AND g.minor_id = 0 AND g.name= 'MS_Description')"
  526. },
  527. { DatabaseType.MySql,
  528. "SELECT TABLE_NAME as Name,table_comment as Description FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA =(select database())"
  529. },
  530. { DatabaseType.Oracle,
  531. "SELECT A.TABLE_NAME AS NAME, B.comments AS DESCRIPTION FROM USER_TABLES A, USER_TAB_COMMENTS B WHERE A.table_name = B.table_name(+)"
  532. },
  533. { DatabaseType.PostgreSql,
  534. "select relname as Name, cast(obj_description(relfilenode,'pg_class') as varchar) as Description from pg_class c where relkind = 'r' and relname not like 'pg_%' and relname not order by relname"
  535. },
  536. { DatabaseType.SQLite,""},
  537. };
  538. /// <summary>
  539. /// 数据库类型表字段sql字典
  540. /// </summary>
  541. private Dictionary<DatabaseType, string> DbTableColumnSqlDic = new Dictionary<DatabaseType, string>()
  542. {
  543. { DatabaseType.SqlServer,
  544. @"
  545. select
  546. sys.columns.name as [Name],
  547. sys.types.name as [Type],
  548. sys.columns.is_nullable [IsNullable],
  549. [IsIdentity]=CONVERT(BIT, (select count(*) from sys.identity_columns where sys.identity_columns.object_id = sys.columns.object_id and sys.columns.column_id = sys.identity_columns.column_id)),
  550. (select value from sys.extended_properties where sys.extended_properties.major_id = sys.columns.object_id and sys.extended_properties.minor_id = sys.columns.column_id and name='MS_Description') as [Description],
  551. [IsKey] =CONVERT(bit,(case when sys.columns.name in (select b.column_name
  552. from information_schema.table_constraints a
  553. inner join information_schema.constraint_column_usage b
  554. on a.constraint_name = b.constraint_name
  555. where a.constraint_type = 'PRIMARY KEY' and a.table_name = @tablename) then 1 else 0 end))
  556. from sys.columns, sys.tables, sys.types where sys.columns.object_id = sys.tables.object_id and sys.columns.system_type_id=sys.types.system_type_id and sys.tables.name=@tablename and sys.types.name !='sysname'
  557. order by sys.columns.column_id asc;"
  558. },
  559. { DatabaseType.MySql,
  560. @"
  561. select DISTINCT
  562. a.COLUMN_NAME as Name,
  563. a.DATA_TYPE as Type,
  564. (a.COLUMN_KEY = 'PRI') as IsKey,
  565. (a.IS_NULLABLE = 'YES') as IsNullable,
  566. a.COLUMN_COMMENT as Description,
  567. a.ORDINAL_POSITION
  568. from information_schema.columns a
  569. where table_name=@tableName and table_schema=(select database())
  570. ORDER BY a.ORDINAL_POSITION;"
  571. },
  572. { DatabaseType.Oracle,
  573. @"
  574. SELECT
  575. A.COLUMN_NAME AS NAME,
  576. A.DATA_TYPE AS TYPE,
  577. NVL2(D.CONSTRAINT_TYPE,1,0) AS ISKEY,
  578. DECODE(A.NULLABLE,'Y',1,0) AS ISNULLABLE,
  579. B.COMMENTS AS DESCRIPTION
  580. FROM USER_TAB_COLUMNS A, USER_COL_COMMENTS B, USER_IND_COLUMNS C, USER_CONSTRAINTS D
  581. WHERE A.TABLE_NAME = B.TABLE_NAME(+)
  582. AND A.COLUMN_NAME = B.COLUMN_NAME(+)
  583. AND A.TABLE_NAME = C.TABLE_NAME(+)
  584. AND A.COLUMN_NAME = C.COLUMN_NAME(+)
  585. AND C.INDEX_NAME = D.INDEX_NAME(+)
  586. AND 'P' = D.CONSTRAINT_TYPE(+)
  587. AND A.TABLE_NAME= :tableName
  588. ORDER BY A.COLUMN_ID;"
  589. },
  590. { DatabaseType.PostgreSql,
  591. @"
  592. SELECT
  593. a.attname as Name,
  594. pg_type.typname as Type,
  595. (SELECT count(1) from(SELECT ic.column_name as ColumnName FROM information_schema.table_constraints tc JOIN information_schema.constraint_column_usage AS ccu USING(constraint_schema, constraint_name) JOIN information_schema.columns AS ic ON ic.table_schema = tc.constraint_schema AND tc.table_name = ic.table_name AND ccu.column_name = ic.column_name
  596. where constraint_type = 'PRIMARY KEY' and tc.table_name = @tablename) KeyA WHERE KeyA.ColumnName = a.attname)> 0 as IsKey,
  597. a.attnotnull<> True as IsNullable,
  598. col_description(a.attrelid, a.attnum) as Description
  599. FROM pg_class as c,pg_attribute as a inner join pg_type on pg_type.oid = a.atttypid
  600. where c.relname = @tablename and a.attrelid = c.oid and a.attnum > 0
  601. order by a.attnum asc;"
  602. }
  603. };
  604. /// <summary>
  605. /// 表信息
  606. /// </summary>
  607. private class TableInfo
  608. {
  609. /// <summary>
  610. /// 表名
  611. /// </summary>
  612. public string Name { get; set; }
  613. /// <summary>
  614. /// 表描述说明
  615. /// </summary>
  616. public string Description
  617. {
  618. get
  619. {
  620. return string.IsNullOrEmpty(_description) ? Name : _description;
  621. }
  622. set
  623. {
  624. _description = value;
  625. }
  626. }
  627. private string _description { get; set; }
  628. }
  629. /// <summary>
  630. /// 表结构信息
  631. /// </summary>
  632. private class TableColumn
  633. {
  634. /// <summary>
  635. /// 字段名
  636. /// </summary>
  637. public string Name { get; set; }
  638. /// <summary>
  639. /// 字段类型
  640. /// </summary>
  641. public string Type { get; set; }
  642. /// <summary>
  643. /// 是否为主键
  644. /// </summary>
  645. public bool IsKey { get; set; }
  646. /// <summary>
  647. /// 是否为空
  648. /// </summary>
  649. public bool IsNullable { get; set; }
  650. /// <summary>
  651. /// 字段描述说明
  652. /// </summary>
  653. public string Description
  654. {
  655. get
  656. {
  657. return string.IsNullOrEmpty(_description) ? Name : _description;
  658. }
  659. set
  660. {
  661. _description = value;
  662. }
  663. }
  664. private string _description { get; set; }
  665. }
  666. }
  667. }