2020-10-22 14:59:36 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.Linq;
|
2021-03-21 10:44:46 +08:00
|
|
|
|
using Autofac.Extensions.DependencyInjection;
|
2020-10-22 14:59:36 +08:00
|
|
|
|
using Infrastructure;
|
2021-04-21 18:02:01 +08:00
|
|
|
|
using Infrastructure.Utilities;
|
|
|
|
|
using Microsoft.AspNetCore.Http;
|
2020-10-22 14:59:36 +08:00
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
2021-03-21 10:44:46 +08:00
|
|
|
|
using Microsoft.EntityFrameworkCore.Internal;
|
|
|
|
|
using Microsoft.EntityFrameworkCore.Metadata;
|
|
|
|
|
using Microsoft.Extensions.Configuration;
|
2020-10-22 14:59:36 +08:00
|
|
|
|
using Microsoft.Extensions.Options;
|
|
|
|
|
using OpenAuth.Repository;
|
|
|
|
|
using OpenAuth.Repository.Domain;
|
|
|
|
|
using OpenAuth.Repository.QueryObj;
|
|
|
|
|
|
|
|
|
|
namespace OpenAuth.App
|
|
|
|
|
{
|
|
|
|
|
public class DbExtension
|
|
|
|
|
{
|
2021-03-21 10:44:46 +08:00
|
|
|
|
private List<DbContext> _contexts = new List<DbContext>();
|
2020-10-22 14:59:36 +08:00
|
|
|
|
|
|
|
|
|
private IOptions<AppSetting> _appConfiguration;
|
2021-04-21 18:02:01 +08:00
|
|
|
|
private IHttpContextAccessor _httpContextAccessor;
|
2020-10-22 14:59:36 +08:00
|
|
|
|
|
2021-04-21 18:02:01 +08:00
|
|
|
|
public DbExtension(IOptions<AppSetting> appConfiguration, OpenAuthDBContext openAuthDbContext, IHttpContextAccessor httpContextAccessor)
|
2020-10-22 14:59:36 +08:00
|
|
|
|
{
|
|
|
|
|
_appConfiguration = appConfiguration;
|
2021-04-21 18:02:01 +08:00
|
|
|
|
_httpContextAccessor = httpContextAccessor;
|
2021-03-21 10:44:46 +08:00
|
|
|
|
_contexts.Add(openAuthDbContext); //如果有多个DBContext,可以按OpenAuthDBContext同样的方式添加到_contexts中
|
2020-10-22 14:59:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取数据库一个表的所有属性值及属性描述
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="moduleName">模块名称/表名</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public List<KeyDescription> GetProperties(string moduleName)
|
|
|
|
|
{
|
|
|
|
|
var result = new List<KeyDescription>();
|
|
|
|
|
const string domain = "openauth.repository.domain.";
|
2021-03-21 10:44:46 +08:00
|
|
|
|
IEntityType entity = null;
|
|
|
|
|
_contexts.ForEach(u =>
|
|
|
|
|
{
|
|
|
|
|
entity = u.Model.GetEntityTypes()
|
|
|
|
|
.FirstOrDefault(u => u.Name.ToLower() == domain + moduleName.ToLower());
|
|
|
|
|
});
|
2020-10-22 14:59:36 +08:00
|
|
|
|
if (entity == null)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception($"未能找到{moduleName}对应的实体类");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var property in entity.ClrType.GetProperties())
|
|
|
|
|
{
|
|
|
|
|
object[] objs = property.GetCustomAttributes(typeof(DescriptionAttribute), true);
|
|
|
|
|
object[] browsableObjs = property.GetCustomAttributes(typeof(BrowsableAttribute), true);
|
|
|
|
|
var description = objs.Length > 0 ? ((DescriptionAttribute) objs[0]).Description : property.Name;
|
|
|
|
|
if (string.IsNullOrEmpty(description)) description = property.Name;
|
|
|
|
|
//如果没有BrowsableAttribute或 [Browsable(true)]表示可见,其他均为不可见,需要前端配合显示
|
|
|
|
|
bool browsable = browsableObjs == null || browsableObjs.Length == 0 ||
|
|
|
|
|
((BrowsableAttribute) browsableObjs[0]).Browsable;
|
|
|
|
|
var typeName = property.PropertyType.Name;
|
|
|
|
|
if (Nullable.GetUnderlyingType(property.PropertyType) != null)
|
|
|
|
|
{
|
|
|
|
|
typeName = Nullable.GetUnderlyingType(property.PropertyType).Name;
|
|
|
|
|
}
|
|
|
|
|
result.Add(new KeyDescription
|
|
|
|
|
{
|
|
|
|
|
Key = property.Name,
|
|
|
|
|
Description = description,
|
|
|
|
|
Browsable = browsable,
|
|
|
|
|
Type = typeName
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取数据库DbContext中所有的实体名称。
|
|
|
|
|
/// <para>注意!并不能获取数据库中的所有表</para>
|
|
|
|
|
/// </summary>
|
|
|
|
|
public List<string> GetDbEntityNames()
|
|
|
|
|
{
|
|
|
|
|
var names = new List<string>();
|
2021-03-21 10:44:46 +08:00
|
|
|
|
var models = _contexts.Select(u =>u.Model);
|
2020-10-22 14:59:36 +08:00
|
|
|
|
|
2021-03-21 10:44:46 +08:00
|
|
|
|
foreach (var model in models)
|
2020-10-22 14:59:36 +08:00
|
|
|
|
{
|
2021-03-21 10:44:46 +08:00
|
|
|
|
// Get all the entity types information contained in the DbContext class, ...
|
|
|
|
|
var entityTypes = model.GetEntityTypes();
|
|
|
|
|
foreach (var entityType in entityTypes)
|
|
|
|
|
{
|
|
|
|
|
var tableNameAnnotation = entityType.GetAnnotation("Relational:TableName");
|
|
|
|
|
names.Add(tableNameAnnotation.Value.ToString());
|
|
|
|
|
}
|
2020-10-22 14:59:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return names;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取数据库表结构信息
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="tableName"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public IList<SysTableColumn> GetDbTableStructure(string tableName)
|
|
|
|
|
{
|
2021-04-21 18:02:01 +08:00
|
|
|
|
var dbtype = _appConfiguration.Value.DbTypes[_httpContextAccessor.GetTenantId()];
|
|
|
|
|
if (dbtype == Define.DBTYPE_MYSQL)
|
2020-10-22 14:59:36 +08:00
|
|
|
|
{
|
|
|
|
|
return GetMySqlStructure(tableName);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return GetSqlServerStructure(tableName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取Mysql表结构信息
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="tableName"></param>
|
|
|
|
|
/// <returns></returns>
|
2021-04-01 23:10:04 +08:00
|
|
|
|
private IList<SysTableColumn> GetMySqlStructure(string tableName)
|
2020-10-22 14:59:36 +08:00
|
|
|
|
{
|
|
|
|
|
var sql = $@"SELECT DISTINCT
|
|
|
|
|
Column_Name AS ColumnName,
|
|
|
|
|
'{ tableName}' as tableName,
|
|
|
|
|
Column_Comment AS Comment,
|
|
|
|
|
data_type as ColumnType,
|
|
|
|
|
CASE
|
|
|
|
|
WHEN data_type IN( 'BIT', 'BOOL', 'bit', 'bool') THEN
|
|
|
|
|
'bool'
|
|
|
|
|
WHEN data_type in('smallint','SMALLINT') THEN 'short'
|
|
|
|
|
WHEN data_type in('tinyint','TINYINT') THEN 'bool'
|
|
|
|
|
WHEN data_type IN('MEDIUMINT','mediumint', 'int','INT','year', 'Year') THEN
|
|
|
|
|
'int'
|
|
|
|
|
WHEN data_type in ( 'BIGINT','bigint') THEN
|
|
|
|
|
'bigint'
|
|
|
|
|
WHEN data_type IN('FLOAT', 'DOUBLE', 'DECIMAL','float', 'double', 'decimal') THEN
|
|
|
|
|
'decimal'
|
|
|
|
|
WHEN data_type IN('CHAR', 'VARCHAR', 'TINY TEXT', 'TEXT', 'MEDIUMTEXT', 'LONGTEXT', 'TINYBLOB', 'BLOB', 'MEDIUMBLOB', 'LONGBLOB', 'Time','char', 'varchar', 'tiny text', 'text', 'mediumtext', 'longtext', 'tinyblob', 'blob', 'mediumblob', 'longblob', 'time') THEN
|
|
|
|
|
'string'
|
|
|
|
|
WHEN data_type IN('Date', 'DateTime', 'TimeStamp','date', 'datetime', 'timestamp') THEN
|
|
|
|
|
'DateTime' ELSE 'string'
|
|
|
|
|
END AS EntityType,
|
|
|
|
|
case WHEN CHARACTER_MAXIMUM_LENGTH>8000 THEN 0 ELSE CHARACTER_MAXIMUM_LENGTH end AS Maxlength,
|
|
|
|
|
CASE
|
2020-12-17 23:04:04 +08:00
|
|
|
|
WHEN COLUMN_KEY = 'PRI' THEN
|
2020-10-22 14:59:36 +08:00
|
|
|
|
1 ELSE 0
|
|
|
|
|
END AS IsKey,
|
|
|
|
|
CASE
|
|
|
|
|
WHEN Column_Name IN( 'CreateID', 'ModifyID', '' )
|
|
|
|
|
OR COLUMN_KEY<> '' THEN
|
|
|
|
|
0 ELSE 1
|
|
|
|
|
END AS IsDisplay,
|
|
|
|
|
1 AS IsColumnData,
|
|
|
|
|
120 AS ColumnWidth,
|
|
|
|
|
0 AS OrderNo,
|
|
|
|
|
CASE
|
|
|
|
|
WHEN IS_NULLABLE = 'NO' THEN
|
|
|
|
|
0 ELSE 1
|
|
|
|
|
END AS IsNull,
|
|
|
|
|
CASE
|
|
|
|
|
WHEN COLUMN_KEY <> '' THEN
|
|
|
|
|
1 ELSE 0
|
|
|
|
|
END AS IsReadDataset
|
|
|
|
|
FROM
|
|
|
|
|
information_schema.COLUMNS
|
|
|
|
|
WHERE
|
2021-04-01 23:10:04 +08:00
|
|
|
|
table_name = '{tableName}'";
|
2021-03-21 10:44:46 +08:00
|
|
|
|
|
|
|
|
|
foreach (var context in _contexts)
|
2020-10-22 14:59:36 +08:00
|
|
|
|
{
|
2021-03-21 10:44:46 +08:00
|
|
|
|
var columns = context.Query<SysTableColumn>().FromSqlRaw(sql);
|
|
|
|
|
var columnList = columns?.ToList();
|
|
|
|
|
if (columnList != null && columnList.Any())
|
2020-10-22 14:59:36 +08:00
|
|
|
|
{
|
2021-03-21 10:44:46 +08:00
|
|
|
|
return columnList;
|
2020-10-22 14:59:36 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-03-21 10:44:46 +08:00
|
|
|
|
|
|
|
|
|
return new List<SysTableColumn>();
|
|
|
|
|
|
2020-10-22 14:59:36 +08:00
|
|
|
|
}
|
2021-03-21 10:44:46 +08:00
|
|
|
|
|
2020-10-22 14:59:36 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取SqlServer表结构信息
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="tableName"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private IList<SysTableColumn> GetSqlServerStructure(string tableName)
|
|
|
|
|
{
|
|
|
|
|
var sql = $@"
|
|
|
|
|
SELECT TableName,
|
|
|
|
|
LTRIM(RTRIM(ColumnName)) AS ColumnName,
|
|
|
|
|
Comment,
|
|
|
|
|
CASE WHEN ColumnType = 'uniqueidentifier' THEN 'guid'
|
|
|
|
|
WHEN ColumnType IN('smallint', 'INT') THEN 'int'
|
|
|
|
|
WHEN ColumnType = 'BIGINT' THEN 'long'
|
|
|
|
|
WHEN ColumnType IN('CHAR', 'VARCHAR', 'NVARCHAR',
|
|
|
|
|
'text', 'xml', 'varbinary', 'image')
|
|
|
|
|
THEN 'string'
|
|
|
|
|
WHEN ColumnType IN('tinyint')
|
|
|
|
|
THEN 'byte'
|
|
|
|
|
WHEN ColumnType IN('bit')
|
|
|
|
|
THEN 'bool'
|
|
|
|
|
|
|
|
|
|
WHEN ColumnType IN('bit') THEN 'bool'
|
|
|
|
|
WHEN ColumnType IN('time', 'date', 'DATETIME', 'smallDATETIME')
|
|
|
|
|
THEN 'DateTime'
|
|
|
|
|
WHEN ColumnType IN('smallmoney', 'DECIMAL', 'numeric',
|
|
|
|
|
'money') THEN 'decimal'
|
|
|
|
|
WHEN ColumnType = 'float' THEN 'float'
|
|
|
|
|
ELSE 'string'
|
|
|
|
|
END as EntityType,
|
|
|
|
|
ColumnType,
|
|
|
|
|
[Maxlength],
|
|
|
|
|
IsKey,
|
|
|
|
|
CASE WHEN ColumnName IN('CreateID', 'ModifyID', '')
|
|
|
|
|
OR IsKey = 1 THEN 0
|
|
|
|
|
ELSE 1
|
|
|
|
|
END AS IsDisplay ,
|
|
|
|
|
1 AS IsColumnData,
|
|
|
|
|
|
|
|
|
|
CASE
|
|
|
|
|
WHEN ColumnName IN('Modifier', 'Creator') THEN 130
|
|
|
|
|
WHEN[Maxlength] < 110 AND[Maxlength] > 60 THEN 120
|
|
|
|
|
WHEN[Maxlength] < 200 AND[Maxlength] >= 110 THEN 180
|
|
|
|
|
WHEN[Maxlength] > 200 THEN 220
|
|
|
|
|
ELSE 90
|
|
|
|
|
END AS ColumnWidth ,
|
|
|
|
|
0 AS OrderNo,
|
|
|
|
|
--CASE WHEN IsKey = 1 OR t.[IsNull]=0 THEN 0
|
|
|
|
|
-- ELSE 1 END
|
|
|
|
|
t.[IsNull] AS
|
|
|
|
|
[IsNull],
|
|
|
|
|
CASE WHEN IsKey = 1 THEN 1 ELSE 0 END IsReadDataset,
|
|
|
|
|
CASE WHEN IsKey!=1 AND t.[IsNull] = 0 THEN 0 ELSE NULL END AS EditColNo
|
|
|
|
|
FROM (SELECT obj.name AS TableName ,
|
|
|
|
|
col.name AS ColumnName ,
|
|
|
|
|
CONVERT(NVARCHAR(100),ISNULL(ep.[value], '')) AS Comment,
|
|
|
|
|
t.name AS ColumnType ,
|
|
|
|
|
CASE WHEN col.length<1 THEN 0 ELSE col.length END AS[Maxlength],
|
|
|
|
|
CASE WHEN EXISTS (SELECT 1
|
|
|
|
|
FROM dbo.sysindexes si
|
|
|
|
|
INNER JOIN dbo.sysindexkeys sik ON si.id = sik.id
|
|
|
|
|
AND si.indid = sik.indid
|
|
|
|
|
INNER JOIN dbo.syscolumns sc ON sc.id = sik.id
|
|
|
|
|
AND sc.colid = sik.colid
|
|
|
|
|
INNER JOIN dbo.sysobjects so ON so.name = si.name
|
|
|
|
|
AND so.xtype = 'PK'
|
|
|
|
|
WHERE sc.id = col.id
|
|
|
|
|
AND sc.colid = col.colid)
|
|
|
|
|
THEN 1
|
|
|
|
|
ELSE 0
|
|
|
|
|
END AS IsKey ,
|
|
|
|
|
CASE WHEN col.isnullable = 1 THEN 1
|
|
|
|
|
ELSE 0
|
|
|
|
|
END AS[IsNull],
|
|
|
|
|
col.colorder
|
|
|
|
|
FROM dbo.syscolumns col
|
|
|
|
|
LEFT JOIN dbo.systypes t ON col.xtype = t.xusertype
|
|
|
|
|
INNER JOIN dbo.sysobjects obj ON col.id = obj.id
|
|
|
|
|
|
|
|
|
|
AND obj.xtype IN ( 'U','V')
|
|
|
|
|
-- AND obj.status >= 01
|
|
|
|
|
LEFT JOIN dbo.syscomments comm ON col.cdefault = comm.id
|
|
|
|
|
LEFT JOIN sys.extended_properties ep ON col.id = ep.major_id
|
|
|
|
|
AND col.colid = ep.minor_id
|
|
|
|
|
AND ep.name = 'MS_Description'
|
|
|
|
|
LEFT JOIN sys.extended_properties epTwo ON obj.id = epTwo.major_id
|
|
|
|
|
AND epTwo.minor_id = 0
|
|
|
|
|
AND epTwo.name = 'MS_Description'
|
|
|
|
|
WHERE obj.name = '{ tableName}') AS t
|
|
|
|
|
ORDER BY t.colorder";
|
|
|
|
|
|
2021-03-21 10:44:46 +08:00
|
|
|
|
foreach (var context in _contexts)
|
|
|
|
|
{
|
|
|
|
|
var columns = context.Query<SysTableColumn>().FromSqlRaw(sql);
|
|
|
|
|
var columnList = columns?.ToList();
|
|
|
|
|
if (columnList != null && columnList.Any())
|
|
|
|
|
{
|
|
|
|
|
return columnList;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return new List<SysTableColumn>();
|
2020-10-22 14:59:36 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|