mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	- 完成 神通数据库所有适配;
This commit is contained in:
		@@ -125,6 +125,13 @@
 | 
				
			|||||||
            清空状态数据
 | 
					            清空状态数据
 | 
				
			||||||
            </summary>
 | 
					            </summary>
 | 
				
			||||||
        </member>
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.DbSet`1.RemoveAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            根据 lambda 条件删除数据
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="predicate"></param>
 | 
				
			||||||
 | 
					            <returns></returns>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
        <member name="M:FreeSql.DbSet`1.Add(`0)">
 | 
					        <member name="M:FreeSql.DbSet`1.Add(`0)">
 | 
				
			||||||
            <summary>
 | 
					            <summary>
 | 
				
			||||||
            添加
 | 
					            添加
 | 
				
			||||||
@@ -479,5 +486,14 @@
 | 
				
			|||||||
            <param name="that"></param>
 | 
					            <param name="that"></param>
 | 
				
			||||||
            <returns></returns>
 | 
					            <returns></returns>
 | 
				
			||||||
        </member>
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            批量注入 Repository,可以参考代码自行调整
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <param name="services"></param>
 | 
				
			||||||
 | 
					            <param name="globalDataFilter"></param>
 | 
				
			||||||
 | 
					            <param name="assemblies"></param>
 | 
				
			||||||
 | 
					            <returns></returns>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
    </members>
 | 
					    </members>
 | 
				
			||||||
</doc>
 | 
					</doc>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,7 @@ namespace FreeSql.Tests.ShenTong
 | 
				
			|||||||
        public void GetTablesByDatabase()
 | 
					        public void GetTablesByDatabase()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var t2 = g.shentong.DbFirst.GetTablesByDatabase(g.shentong.DbFirst.GetDatabases()[1]);
 | 
					            var t2 = g.shentong.DbFirst.GetTablesByDatabase(g.shentong.DbFirst.GetDatabases()[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1373,7 +1373,7 @@
 | 
				
			|||||||
            Sqlite: 无效果<para></para>
 | 
					            Sqlite: 无效果<para></para>
 | 
				
			||||||
            达梦: for update nowait<para></para>
 | 
					            达梦: for update nowait<para></para>
 | 
				
			||||||
            人大金仓: for update nowait<para></para>
 | 
					            人大金仓: for update nowait<para></para>
 | 
				
			||||||
            神通: for update nowait
 | 
					            神通: for update
 | 
				
			||||||
            </summary>
 | 
					            </summary>
 | 
				
			||||||
            <param name="nowait">noawait</param>
 | 
					            <param name="nowait">noawait</param>
 | 
				
			||||||
            <returns></returns>
 | 
					            <returns></returns>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
FreeSql.Provider.Odbc 实现 ODBC 访问数据库,ODBC 属于比较原始的技术,更新慢,各大数据库厂支持得标准不一,不到万不得已最好别用 odbc,坑比较多。
 | 
					FreeSql.Provider.Odbc 实现 ODBC 访问数据库,ODBC 属于比较原始的技术,更新慢,各大数据库厂支持得标准不一,不到万不得已最好别用 odbc,坑比较多。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FreeSql.Provider.Odbc 做了四种数据库的专用实现:SqlServer、PostgreSQL、Oracle、MySql,和一种通用实现。
 | 
					FreeSql.Provider.Odbc 做了四种数据库的专用实现:SqlServer、PostgreSQL、Oracle、MySql、达梦、人大金仓,和一种通用实现。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
专用实现比较有针对性,和原来的 FreeSql.Provider.SqlServer ado.net 相比,只支持较少的基础类型,其他功能几乎都有,包括 CodeFirst 自动迁移。
 | 
					专用实现比较有针对性,和原来的 FreeSql.Provider.SqlServer ado.net 相比,只支持较少的基础类型,其他功能几乎都有,包括 CodeFirst 自动迁移。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -143,17 +143,16 @@ namespace FreeSql.ShenTong
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                var sql = $@"
 | 
					                var sql = $@"
 | 
				
			||||||
select
 | 
					select
 | 
				
			||||||
b.nspname || '.' || a.tablename,
 | 
					b.nspname || '.' || a.relname,
 | 
				
			||||||
a.schemaname,
 | 
					b.nspname,
 | 
				
			||||||
a.tablename ,
 | 
					a.relname,
 | 
				
			||||||
d.description,
 | 
					d.description,
 | 
				
			||||||
'TABLE'
 | 
					'TABLE'
 | 
				
			||||||
from sys_tables a
 | 
					from sys_class a
 | 
				
			||||||
inner join sys_namespace b on b.nspname = a.schemaname
 | 
					inner join sys_namespace b on b.oid = a.relnamespace
 | 
				
			||||||
inner join sys_class c on c.relnamespace = b.oid and c.relname = a.tablename
 | 
					left join sys_description d on d.objoid = a.oid and objsubid = 0
 | 
				
			||||||
left join sys_description d on d.objoid = c.oid and objsubid = 0
 | 
					where b.nspname not in ('DIRECTORIES', 'INFO_SCHEM', 'REPLICATION', 'STAGENT', 'SYSAUDIT', 'SYSDBA', 'SYSFTSDBA', 'SYSSECURE', 'SYS_GLOBAL_TEMP', 'WMSYS') and a.relkind in ('r') 
 | 
				
			||||||
where a.schemaname not in ('DIRECTORIES', 'INFO_SCHEM', 'REPLICATION', 'STAGENT', 'SYSAUDIT', 'SYSDBA', 'SYSFTSDBA', 'SYSSECURE', 'SYS_GLOBAL_TEMP', 'WMSYS')
 | 
					and b.nspname || '.' || a.relname not in ('PUBLIC.SPATIAL_REF_SYS')
 | 
				
			||||||
and b.nspname || '.' || a.tablename not in ('PUBLIC.SPATIAL_REF_SYS')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
union all
 | 
					union all
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -167,7 +166,7 @@ from sys_class a
 | 
				
			|||||||
inner join sys_namespace b on b.oid = a.relnamespace
 | 
					inner join sys_namespace b on b.oid = a.relnamespace
 | 
				
			||||||
left join sys_description d on d.objoid = a.oid and objsubid = 0
 | 
					left join sys_description d on d.objoid = a.oid and objsubid = 0
 | 
				
			||||||
where b.nspname not in ('DIRECTORIES', 'INFO_SCHEM', 'REPLICATION', 'STAGENT', 'SYSAUDIT', 'SYSDBA', 'SYSFTSDBA', 'SYSSECURE', 'SYS_GLOBAL_TEMP', 'WMSYS') and a.relkind in ('m','v') 
 | 
					where b.nspname not in ('DIRECTORIES', 'INFO_SCHEM', 'REPLICATION', 'STAGENT', 'SYSAUDIT', 'SYSDBA', 'SYSFTSDBA', 'SYSSECURE', 'SYS_GLOBAL_TEMP', 'WMSYS') and a.relkind in ('m','v') 
 | 
				
			||||||
and b.nspname || '.' || a.relname not in ('PUBLIC.GEOGRAPHY_COLUMNS','PUBLIC.GEOMETRY_COLUMNS','PUBLIC.RASTER_COLUMNS','PUBLIC.RASTER_OVERVIEWS')
 | 
					and b.nspname || '.' || a.relname not in ('PUBLIC.GEOGRAPHY_COLUMNS','PUBLIC.GEOMETRY_COLUMNS','PUBLIC.RASTER_COLUMNS','PUBLIC.RASTER_OVERVIEWS','PUBLIC.DBA_JOBS')
 | 
				
			||||||
";
 | 
					";
 | 
				
			||||||
                var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
 | 
					                var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
 | 
				
			||||||
                if (ds == null) return loc1;
 | 
					                if (ds == null) return loc1;
 | 
				
			||||||
@@ -260,7 +259,7 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname")
 | 
				
			|||||||
                    var max_length = int.Parse(string.Concat(row[3]));
 | 
					                    var max_length = int.Parse(string.Concat(row[3]));
 | 
				
			||||||
                    var sqlType = string.Concat(row[4]);
 | 
					                    var sqlType = string.Concat(row[4]);
 | 
				
			||||||
                    var is_nullable = string.Concat(row[5]) == "1";
 | 
					                    var is_nullable = string.Concat(row[5]) == "1";
 | 
				
			||||||
                    var is_identity = string.Concat(row[6]).StartsWith(@"NEXTVAL('") && string.Concat(row[6]).EndsWith(@"'::REGCLASS)");
 | 
					                    var is_identity = string.Concat(row[6]).StartsWith(@"NEXTVAL('") && string.Concat(row[6]).EndsWith(@"'::text)");
 | 
				
			||||||
                    var comment = string.Concat(row[7]);
 | 
					                    var comment = string.Concat(row[7]);
 | 
				
			||||||
                    var defaultValue = string.Concat(row[6]);
 | 
					                    var defaultValue = string.Concat(row[6]);
 | 
				
			||||||
                    int attndims = int.Parse(string.Concat(row[8]));
 | 
					                    int attndims = int.Parse(string.Concat(row[8]));
 | 
				
			||||||
@@ -314,8 +313,9 @@ b.relname as index_id,
 | 
				
			|||||||
case when a.indisunique then 1 else 0 end IsUnique,
 | 
					case when a.indisunique then 1 else 0 end IsUnique,
 | 
				
			||||||
case when a.indisprimary then 1 else 0 end IsPrimary,
 | 
					case when a.indisprimary then 1 else 0 end IsPrimary,
 | 
				
			||||||
case when a.indisclustered then 0 else 1 end IsClustered,
 | 
					case when a.indisclustered then 0 else 1 end IsClustered,
 | 
				
			||||||
case when sys_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc,
 | 
					--case when sys_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc,
 | 
				
			||||||
a.indkey::text,
 | 
					0,
 | 
				
			||||||
 | 
					a.indkey,
 | 
				
			||||||
c.attnum
 | 
					c.attnum
 | 
				
			||||||
from sys_index a
 | 
					from sys_index a
 | 
				
			||||||
inner join sys_class b on b.oid = a.indexrelid
 | 
					inner join sys_class b on b.oid = a.indexrelid
 | 
				
			||||||
@@ -385,50 +385,41 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname")
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                sql = $@"
 | 
					                sql = $@"
 | 
				
			||||||
select
 | 
					select
 | 
				
			||||||
ns.nspname || '.' || b.relname as table_id, 
 | 
					a.pktable_schem || '.' || a.pktable_name,
 | 
				
			||||||
array(select attname from sys_attribute where attrelid = a.conrelid and attnum = any(a.conkey)) as column_name,
 | 
					a.pkcolumn_name,
 | 
				
			||||||
a.conname as FKId,
 | 
					a.fk_name,
 | 
				
			||||||
ns2.nspname || '.' || c.relname as ref_table_id, 
 | 
					a.fktable_schem || '.' || a.fktable_name,
 | 
				
			||||||
1 as IsForeignKey,
 | 
					1,
 | 
				
			||||||
array(select attname from sys_attribute where attrelid = a.confrelid and attnum = any(a.confkey)) as ref_column,
 | 
					a.fkcolumn_name
 | 
				
			||||||
null ref_sln,
 | 
					from v_sys_foreign_keys a
 | 
				
			||||||
null ref_table
 | 
					where {loc8.ToString().Replace("a.table_name", "a.pktable_schem || '.' || a.pktable_name")}
 | 
				
			||||||
from  sys_constraint a
 | 
					 | 
				
			||||||
inner join sys_class b on b.oid = a.conrelid
 | 
					 | 
				
			||||||
inner join sys_class c on c.oid = a.confrelid
 | 
					 | 
				
			||||||
inner join sys_namespace ns on ns.oid = b.relnamespace
 | 
					 | 
				
			||||||
inner join sys_namespace ns2 on ns2.oid = c.relnamespace
 | 
					 | 
				
			||||||
where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || b.relname")}
 | 
					 | 
				
			||||||
";
 | 
					";
 | 
				
			||||||
                ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
 | 
					                ds = _orm.Ado.ExecuteArray(CommandType.Text, sql);
 | 
				
			||||||
                if (ds == null) return loc1;
 | 
					                if (ds == null) return loc1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var fkColumns = new Dictionary<string, Dictionary<string, DbForeignInfo>>();
 | 
					                var fkColumns = new Dictionary<string, Dictionary<string, DbForeignInfo>>();
 | 
				
			||||||
                foreach (object[] row in ds)
 | 
					                foreach (var row in ds)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var table_id = string.Concat(row[0]);
 | 
					                    string table_id = string.Concat(row[0]);
 | 
				
			||||||
                    var column = row[1] as string[];
 | 
					                    string column = string.Concat(row[1]);
 | 
				
			||||||
                    var fk_id = string.Concat(row[2]);
 | 
					                    string fk_id = string.Concat(row[2]);
 | 
				
			||||||
                    var ref_table_id = string.Concat(row[3]);
 | 
					                    string ref_table_id = string.Concat(row[3]);
 | 
				
			||||||
                    var is_foreign_key = string.Concat(row[4]) == "1";
 | 
					                    bool is_foreign_key = string.Concat(row[4]) == "1";
 | 
				
			||||||
                    var referenced_column = row[5] as string[];
 | 
					                    string referenced_column = string.Concat(row[5]);
 | 
				
			||||||
                    var referenced_db = string.Concat(row[6]);
 | 
					                    if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue;
 | 
				
			||||||
                    var referenced_table = string.Concat(row[7]);
 | 
					                    var loc9 = loc3[table_id][column];
 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (loc2.ContainsKey(ref_table_id) == false) continue;
 | 
					                    if (loc2.ContainsKey(ref_table_id) == false) continue;
 | 
				
			||||||
 | 
					                    var loc10 = loc2[ref_table_id];
 | 
				
			||||||
 | 
					                    var loc11 = loc3[ref_table_id][referenced_column];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    Dictionary<string, DbForeignInfo> loc12 = null;
 | 
					                    Dictionary<string, DbForeignInfo> loc12 = null;
 | 
				
			||||||
                    DbForeignInfo loc13 = null;
 | 
					                    DbForeignInfo loc13 = null;
 | 
				
			||||||
                    if (!fkColumns.TryGetValue(table_id, out loc12))
 | 
					                    if (!fkColumns.TryGetValue(table_id, out loc12))
 | 
				
			||||||
                        fkColumns.Add(table_id, loc12 = new Dictionary<string, DbForeignInfo>());
 | 
					                        fkColumns.Add(table_id, loc12 = new Dictionary<string, DbForeignInfo>());
 | 
				
			||||||
                    if (!loc12.TryGetValue(fk_id, out loc13))
 | 
					                    if (!loc12.TryGetValue(fk_id, out loc13))
 | 
				
			||||||
                        loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc2[ref_table_id] });
 | 
					                        loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 });
 | 
				
			||||||
 | 
					                    loc13.Columns.Add(loc9);
 | 
				
			||||||
                    for (int a = 0; a < column.Length; a++)
 | 
					                    loc13.ReferencedColumns.Add(loc11);
 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        loc13.Columns.Add(loc3[table_id][column[a]]);
 | 
					 | 
				
			||||||
                        loc13.ReferencedColumns.Add(loc3[ref_table_id][referenced_column[a]]);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                foreach (var table_id in fkColumns.Keys)
 | 
					                foreach (var table_id in fkColumns.Keys)
 | 
				
			||||||
                    foreach (var fk in fkColumns[table_id])
 | 
					                    foreach (var fk in fkColumns[table_id])
 | 
				
			||||||
@@ -482,32 +473,6 @@ where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || b.relname")
 | 
				
			|||||||
            return tables;
 | 
					            return tables;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public class GetEnumsByDatabaseQueryInfo
 | 
					        public List<DbEnumInfo> GetEnumsByDatabase(params string[] database) => new List<DbEnumInfo>();
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            public string name { get; set; }
 | 
					 | 
				
			||||||
            public string label { get; set; }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        public List<DbEnumInfo> GetEnumsByDatabase(params string[] database)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (database == null || database.Length == 0) return new List<DbEnumInfo>();
 | 
					 | 
				
			||||||
            var drs = _orm.Ado.Query<GetEnumsByDatabaseQueryInfo>(CommandType.Text, _commonUtils.FormatSql(@"
 | 
					 | 
				
			||||||
select
 | 
					 | 
				
			||||||
ns.nspname || '.' || a.typname AS name,
 | 
					 | 
				
			||||||
b.enumlabel AS label
 | 
					 | 
				
			||||||
from sys_type a
 | 
					 | 
				
			||||||
inner join sys_enum b on b.enumtypid = a.oid
 | 
					 | 
				
			||||||
inner join sys_namespace ns on ns.oid = a.typnamespace
 | 
					 | 
				
			||||||
where a.typtype = 'e' and ns.nspname in (SELECT schema_name FROM information_schema.schemata where catalog_name in {0})", database));
 | 
					 | 
				
			||||||
            var ret = new Dictionary<string, Dictionary<string, string>>();
 | 
					 | 
				
			||||||
            foreach (var dr in drs)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (ret.TryGetValue(dr.name, out var labels) == false) ret.Add(dr.name, labels = new Dictionary<string, string>());
 | 
					 | 
				
			||||||
                var key = dr.label;
 | 
					 | 
				
			||||||
                if (Regex.IsMatch(key, @"^[\u0391-\uFFE5a-zA-Z_\$][\u0391-\uFFE5a-zA-Z_\$\d]*$") == false)
 | 
					 | 
				
			||||||
                    key = $"Unkown{ret[dr.name].Count + 1}";
 | 
					 | 
				
			||||||
                if (labels.ContainsKey(key) == false) labels.Add(key, dr.label);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return ret.Select(a => new DbEnumInfo { Name = a.Key, Labels = a.Value }).ToList();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -32,7 +32,7 @@ namespace FreeSql.ShenTong
 | 
				
			|||||||
        public IAdo Ado { get; }
 | 
					        public IAdo Ado { get; }
 | 
				
			||||||
        public IAop Aop { get; }
 | 
					        public IAop Aop { get; }
 | 
				
			||||||
        public ICodeFirst CodeFirst { get; }
 | 
					        public ICodeFirst CodeFirst { get; }
 | 
				
			||||||
        public IDbFirst DbFirst => throw new NotImplementedException("正在支持中");
 | 
					        public IDbFirst DbFirst { get; }
 | 
				
			||||||
        public ShenTongProvider(string masterConnectionString, string[] slaveConnectionString, Func<DbConnection> connectionFactory = null)
 | 
					        public ShenTongProvider(string masterConnectionString, string[] slaveConnectionString, Func<DbConnection> connectionFactory = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            this.InternalCommonUtils = new ShenTongUtils(this);
 | 
					            this.InternalCommonUtils = new ShenTongUtils(this);
 | 
				
			||||||
@@ -41,7 +41,7 @@ namespace FreeSql.ShenTong
 | 
				
			|||||||
            this.Ado = new ShenTongAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory);
 | 
					            this.Ado = new ShenTongAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory);
 | 
				
			||||||
            this.Aop = new AopProvider();
 | 
					            this.Aop = new AopProvider();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //this.DbFirst = new ShenTongDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
					            this.DbFirst = new ShenTongDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
				
			||||||
            this.CodeFirst = new ShenTongCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
					            this.CodeFirst = new ShenTongCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user