.NET Core实战项目之CMS 第十一章 开发篇-数据库生成及实体代码生成器开发 (3)

首先我们创建一个Option对象来接收我们所需要的参数,比如说:数据库类型,数据库连接字符串,作者,实体模型的命名空间等等,如下所示:

/// <summary> /// yilezhu /// 2018.12.12 /// 代码生成选项 /// </summary> public class CodeGenerateOption { /// <summary> /// 数据库连接字符串 /// </summary> public string ConnectionString { get; set; } /// <summary> /// 数据库类型 /// </summary> public string DbType { get; set; } /// <summary> /// 作者 /// </summary> public string Author { get; set; } /// <summary> /// 代码生成时间 /// </summary> public string GeneratorTime { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); /// <summary> /// 输出路径 /// </summary> public string OutputPath { get; set; } /// <summary> /// 实体命名空间 /// </summary> public string ModelsNamespace { get; set; } }

从数据库里面获取所有表的脚本,这里我只是简单的实现了下SqlServer的代码,后续我会对这块进行提取封装,并支持MySql,Oracle,PSQL等等:

//TODO 从数据库获取表列表以及生成实体对象 if (_options.DbType != DatabaseType.SqlServer.ToString()) throw new ArgumentNullException("这是我的错,目前只支持MSSQL数据库的代码生成!后续更新MySQL"); DatabaseType dbType = DatabaseType.SqlServer; string strGetAllTables = @"SELECT DISTINCT d.name as TableName, f.value as TableComment FROM sys.syscolumns AS a LEFT OUTER JOIN sys.systypes AS b ON a.xusertype = b.xusertype INNER JOIN sys.sysobjects AS d ON a.id = d.id AND d.xtype = 'U' AND d.name <> 'dtproperties' LEFT OUTER JOIN sys.syscomments AS e ON a.cdefault = e.id LEFT OUTER JOIN sys.extended_properties AS g ON a.id = g.major_id AND a.colid = g.minor_id LEFT OUTER JOIN sys.extended_properties AS f ON d.id = f.major_id AND f.minor_id = 0"; List<DbTable> tables = null; using (var conn = new SqlConnection(_options.ConnectionString)) { tables = conn.Query<DbTable>(strGetAllTables).ToList();

遍历每个表然后获取每个表对应的列(也是只实现的SqlServer的代码)

tables.ForEach(item => { string strGetTableColumns = @"SELECT a.name AS ColName, CONVERT(bit, (CASE WHEN COLUMNPROPERTY(a.id, a.name, 'IsIdentity') = 1 THEN 1 ELSE 0 END)) AS IsIdentity, CONVERT(bit, (CASE WHEN (SELECT COUNT(*) FROM sysobjects WHERE (name IN (SELECT name FROM sysindexes WHERE (id = a.id) AND (indid IN (SELECT indid FROM sysindexkeys WHERE (id = a.id) AND (colid IN (SELECT colid FROM syscolumns WHERE (id = a.id) AND (name = a.name))))))) AND (xtype = 'PK')) > 0 THEN 1 ELSE 0 END)) AS IsPrimaryKey, b.name AS ColumnType, COLUMNPROPERTY(a.id, a.name, 'PRECISION') AS ColumnLength, CONVERT(bit, (CASE WHEN a.isnullable = 1 THEN 1 ELSE 0 END)) AS IsNullable, ISNULL(e.text, '') AS DefaultValue, ISNULL(g.value, ' ') AS Comment FROM sys.syscolumns AS a LEFT OUTER JOIN sys.systypes AS b ON a.xtype = b.xusertype INNER JOIN sys.sysobjects AS d ON a.id = d.id AND d.xtype = 'U' AND d.name <> 'dtproperties' LEFT OUTER JOIN sys.syscomments AS e ON a.cdefault = e.id LEFT OUTER JOIN sys.extended_properties AS g ON a.id = g.major_id AND a.colid = g.minor_id LEFT OUTER JOIN sys.extended_properties AS f ON d.id = f.class AND f.minor_id = 0 WHERE (b.name IS NOT NULL) AND (d.name = @TableName) ORDER BY a.id, a.colorder"; item.Columns = conn.Query<DbTableColumn>(strGetTableColumns, new { TableName = item.TableName }).ToList();

接下来就是对数据库获取的列进行一个转换,根据数据库字段类型转换成对应的C#类型了

item.Columns.ForEach(x => { var csharpType = DbColumnTypeCollection.DbColumnDataTypes.FirstOrDefault(t => t.DatabaseType == dbType && t.ColumnTypes.Split(',').Any(p => p.Trim().Equals(x.ColumnType, StringComparison.OrdinalIgnoreCase)))?.CSharpType; if (string.IsNullOrEmpty(csharpType)) { throw new SqlTypeException($"未从字典中找到\"{x.ColumnType}\"对应的C#数据类型,请更新DbColumnTypeCollection类型映射字典。"); } x.CSharpType = csharpType; });

既然所有的表以及表对应的列我们都拿到了,那么我们就可以进行代码的生成了,当然在生成之前还得创建我们的模板文件:

// 本代码由代码生成器生成请勿随意改动 // 生成时间 {GeneratorTime} using System; namespace {ModelsNamespace} { /// <summary> /// {Author} /// {GeneratorTime} /// {Comment} /// </summary> public class {ModelName} { {ModelProperties} } }

看到没有,很简单的POCO对象的样子,接下来就是生成对应的模板了,具体怎么生成呢?思考下:是不是首先读取模板文件到一个string里面,然后就是简单的replace了!很简单吧,具体的代码我都上传到了Github上,文章末尾我会给出地址。另外为了大家引用的方便我已经把这个Czar.Cms.Core项目制作成了Nuget包,大家只需要搜索这个包引用下就可以用了!什么?Nuget包怎么引用啊?骚年你可以上天了~~~~~

测试实体代码生成器

Czar.Cms.Test 这个项目添加Nuget包引用,引用后的Nuget如下所示:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wspyxd.html