mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	- 优化 兼容 pgsql 9.4 CodeFirst/DbFirst;
This commit is contained in:
		@@ -125,13 +125,6 @@
 | 
				
			|||||||
            清空状态数据
 | 
					            清空状态数据
 | 
				
			||||||
            </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>
 | 
				
			||||||
            添加
 | 
					            添加
 | 
				
			||||||
@@ -486,14 +479,5 @@
 | 
				
			|||||||
            <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>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -84,6 +84,12 @@ namespace FreeSql.Odbc.PostgreSQL
 | 
				
			|||||||
            var sb = new StringBuilder();
 | 
					            var sb = new StringBuilder();
 | 
				
			||||||
            var seqcols = new List<NaviteTuple<ColumnInfo, string[], bool>>(); //序列
 | 
					            var seqcols = new List<NaviteTuple<ColumnInfo, string[], bool>>(); //序列
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var is96 = true;
 | 
				
			||||||
 | 
					            using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                is96 = OdbcPostgreSQLDbFirst.PgVersionIs96(conn.Value.ServerVersion);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var obj in objects)
 | 
					            foreach (var obj in objects)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (sb.Length > 0) sb.Append("\r\n");
 | 
					                if (sb.Length > 0) sb.Append("\r\n");
 | 
				
			||||||
@@ -262,24 +268,24 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname);
 | 
				
			|||||||
                        if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true));
 | 
					                        if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NaviteTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true));
 | 
				
			||||||
                        if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n");
 | 
					                        if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n");
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    var dsuksql = _commonUtils.FormatSql(@"
 | 
					                    var dsuksql = _commonUtils.FormatSql($@"
 | 
				
			||||||
select
 | 
					select
 | 
				
			||||||
c.attname,
 | 
					c.attname,
 | 
				
			||||||
b.relname,
 | 
					b.relname,
 | 
				
			||||||
case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc,
 | 
					{(is96 ? "case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end" : "0")} IsDesc,
 | 
				
			||||||
case when indisunique = 't' then 1 else 0 end IsUnique
 | 
					case when indisunique = 't' then 1 else 0 end IsUnique
 | 
				
			||||||
from pg_index a
 | 
					from pg_index a
 | 
				
			||||||
inner join pg_class b on b.oid = a.indexrelid
 | 
					inner join pg_class b on b.oid = a.indexrelid
 | 
				
			||||||
inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid
 | 
					inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid
 | 
				
			||||||
inner join pg_namespace ns on ns.oid = b.relnamespace
 | 
					inner join pg_namespace ns on ns.oid = b.relnamespace
 | 
				
			||||||
inner join pg_class d on d.oid = a.indrelid
 | 
					inner join pg_class d on d.oid = a.indrelid
 | 
				
			||||||
where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tboldname ?? tbname);
 | 
					where ns.nspname in ({{0}}) and d.relname in ({{1}}) and a.indisprimary = 'f'", tboldname ?? tbname);
 | 
				
			||||||
                    var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) });
 | 
					                    var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) });
 | 
				
			||||||
                    foreach (var uk in tb.Indexes)
 | 
					                    foreach (var uk in tb.Indexes)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue;
 | 
					                        if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue;
 | 
				
			||||||
                        var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray();
 | 
					                        var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray();
 | 
				
			||||||
                        if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length)
 | 
					                        if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && ((a[2] == "1") == b.IsDesc || is96 == false)).Any()).Count() != uk.Columns.Length)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(";\r\n");
 | 
					                            if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(";\r\n");
 | 
				
			||||||
                            sbalter.Append("CREATE ");
 | 
					                            sbalter.Append("CREATE ");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -103,9 +103,11 @@ namespace FreeSql.Odbc.PostgreSQL
 | 
				
			|||||||
        public List<DbTableInfo> GetTablesByDatabase(params string[] database)
 | 
					        public List<DbTableInfo> GetTablesByDatabase(params string[] database)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var olddatabase = "";
 | 
					            var olddatabase = "";
 | 
				
			||||||
 | 
					            var is96 = true;
 | 
				
			||||||
            using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)))
 | 
					            using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                olddatabase = conn.Value.Database;
 | 
					                olddatabase = conn.Value.Database;
 | 
				
			||||||
 | 
					                is96 = PgVersionIs96(conn.Value.ServerVersion);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database;
 | 
					            var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database;
 | 
				
			||||||
            var tables = new List<DbTableInfo>();
 | 
					            var tables = new List<DbTableInfo>();
 | 
				
			||||||
@@ -291,7 +293,7 @@ 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 pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc,
 | 
					{(is96 ? "case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end" : "0")} IsDesc,
 | 
				
			||||||
a.indkey::text,
 | 
					a.indkey::text,
 | 
				
			||||||
c.attnum
 | 
					c.attnum
 | 
				
			||||||
from pg_index a
 | 
					from pg_index a
 | 
				
			||||||
@@ -486,5 +488,14 @@ where a.typtype = 'e' and ns.nspname in (SELECT ""schema_name"" FROM information
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            return ret.Select(a => new DbEnumInfo { Name = a.Key, Labels = a.Value }).ToList();
 | 
					            return ret.Select(a => new DbEnumInfo { Name = a.Key, Labels = a.Value }).ToList();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static bool PgVersionIs96(string serverVersion)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int[] version = serverVersion.Split('.').Select(a => int.TryParse(a, out var tryint) ? tryint : 0).ToArray();
 | 
				
			||||||
 | 
					            if (version?.Any() != true) return true;
 | 
				
			||||||
 | 
					            if (version[0] > 9) return true;
 | 
				
			||||||
 | 
					            if (version[0] == 9 && version.Length > 1 && version[1] >= 6) return true;
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -119,6 +119,12 @@ namespace FreeSql.PostgreSQL
 | 
				
			|||||||
            var sb = new StringBuilder();
 | 
					            var sb = new StringBuilder();
 | 
				
			||||||
            var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列
 | 
					            var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var is96 = true;
 | 
				
			||||||
 | 
					            using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                is96 = PostgreSQLDbFirst.PgVersionIs96(conn.Value.ServerVersion);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var obj in objects)
 | 
					            foreach (var obj in objects)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (sb.Length > 0) sb.Append("\r\n");
 | 
					                if (sb.Length > 0) sb.Append("\r\n");
 | 
				
			||||||
@@ -297,24 +303,24 @@ where ns.nspname = {0} and c.relname = {1}", tboldname ?? tbname);
 | 
				
			|||||||
                        if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true));
 | 
					                        if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true));
 | 
				
			||||||
                        if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n");
 | 
					                        if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n");
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    var dsuksql = _commonUtils.FormatSql(@"
 | 
					                    var dsuksql = _commonUtils.FormatSql($@"
 | 
				
			||||||
select
 | 
					select
 | 
				
			||||||
c.attname,
 | 
					c.attname,
 | 
				
			||||||
b.relname,
 | 
					b.relname,
 | 
				
			||||||
case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc,
 | 
					{(is96 ? "case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end" : "0")} IsDesc,
 | 
				
			||||||
case when indisunique = 't' then 1 else 0 end IsUnique
 | 
					case when indisunique = 't' then 1 else 0 end IsUnique
 | 
				
			||||||
from pg_index a
 | 
					from pg_index a
 | 
				
			||||||
inner join pg_class b on b.oid = a.indexrelid
 | 
					inner join pg_class b on b.oid = a.indexrelid
 | 
				
			||||||
inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid
 | 
					inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid
 | 
				
			||||||
inner join pg_namespace ns on ns.oid = b.relnamespace
 | 
					inner join pg_namespace ns on ns.oid = b.relnamespace
 | 
				
			||||||
inner join pg_class d on d.oid = a.indrelid
 | 
					inner join pg_class d on d.oid = a.indrelid
 | 
				
			||||||
where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tboldname ?? tbname);
 | 
					where ns.nspname in ({{0}}) and d.relname in ({{1}}) and a.indisprimary = 'f'", tboldname ?? tbname);
 | 
				
			||||||
                    var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) });
 | 
					                    var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) });
 | 
				
			||||||
                    foreach (var uk in tb.Indexes)
 | 
					                    foreach (var uk in tb.Indexes)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue;
 | 
					                        if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue;
 | 
				
			||||||
                        var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray();
 | 
					                        var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Name, true) == 0).ToArray();
 | 
				
			||||||
                        if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length)
 | 
					                        if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && ((a[2] == "1") == b.IsDesc || is96 == false)).Any()).Count() != uk.Columns.Length)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(";\r\n");
 | 
					                            if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Name)).Append(";\r\n");
 | 
				
			||||||
                            sbalter.Append("CREATE ");
 | 
					                            sbalter.Append("CREATE ");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -213,9 +213,11 @@ namespace FreeSql.PostgreSQL
 | 
				
			|||||||
        public List<DbTableInfo> GetTablesByDatabase(params string[] database)
 | 
					        public List<DbTableInfo> GetTablesByDatabase(params string[] database)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var olddatabase = "";
 | 
					            var olddatabase = "";
 | 
				
			||||||
 | 
					            var is96 = true;
 | 
				
			||||||
            using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)))
 | 
					            using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                olddatabase = conn.Value.Database;
 | 
					                olddatabase = conn.Value.Database;
 | 
				
			||||||
 | 
					                is96 = PgVersionIs96(conn.Value.ServerVersion);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database;
 | 
					            var dbs = database == null || database.Any() == false ? new[] { olddatabase } : database;
 | 
				
			||||||
            var tables = new List<DbTableInfo>();
 | 
					            var tables = new List<DbTableInfo>();
 | 
				
			||||||
@@ -401,7 +403,7 @@ 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 pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end IsDesc,
 | 
					{(is96 ? "case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end" : "0")} IsDesc,
 | 
				
			||||||
a.indkey::text,
 | 
					a.indkey::text,
 | 
				
			||||||
c.attnum
 | 
					c.attnum
 | 
				
			||||||
from pg_index a
 | 
					from pg_index a
 | 
				
			||||||
@@ -591,5 +593,14 @@ where a.typtype = 'e' and ns.nspname in (SELECT ""schema_name"" FROM information
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            return ret.Select(a => new DbEnumInfo { Name = a.Key, Labels = a.Value }).ToList();
 | 
					            return ret.Select(a => new DbEnumInfo { Name = a.Key, Labels = a.Value }).ToList();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static bool PgVersionIs96(string serverVersion)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            int[] version = serverVersion.Split('.').Select(a => int.TryParse(a, out var tryint) ? tryint : 0).ToArray();
 | 
				
			||||||
 | 
					            if (version?.Any() != true) return true;
 | 
				
			||||||
 | 
					            if (version[0] > 9) return true;
 | 
				
			||||||
 | 
					            if (version[0] == 9 && version.Length > 1 && version[1] >= 6) return true;
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user