mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 01:05:27 +08:00 
			
		
		
		
	- 增加 AsTable 和 Repository 分表时的自动迁移分表功能;
- 增加 ICodeFirst.SyncStructure(Type entityType, string tableName) 指定表名来迁移实体; ```csharp fsql.CodeFirst.SyncStructure(typeof(Log), "Log_1"); //迁移到 Log_1 表 fsql.CodeFirst.SyncStructure(typeof(Log), "Log_2"); //迁移到 Log_2 表 ```
This commit is contained in:
		@@ -99,13 +99,6 @@
 | 
			
		||||
            清空状态数据
 | 
			
		||||
            </summary>
 | 
			
		||||
        </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)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            添加
 | 
			
		||||
 
 | 
			
		||||
@@ -821,65 +821,66 @@ namespace FreeSql.Tests.Odbc.Oracle
 | 
			
		||||
 | 
			
		||||
            Func<Type, string, string> tableRule = (type, oldname) =>
 | 
			
		||||
            {
 | 
			
		||||
                if (type == typeof(Topic)) return oldname + "AsTable1";
 | 
			
		||||
                else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2";
 | 
			
		||||
                return oldname + "AsTable";
 | 
			
		||||
                if (oldname.Length > 16) oldname = oldname.Remove(16);
 | 
			
		||||
                if (type == typeof(Topic)) return oldname + "_T1";
 | 
			
		||||
                else if (type == typeof(TestTypeInfo)) return oldname + "_T2";
 | 
			
		||||
                return oldname + "_AT";
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            //<2F><><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>a.Type<70><65>a.Type.Parent <20><><EFBFBD>ǵ<EFBFBD><C7B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
            var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule);
 | 
			
		||||
            var sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql);
 | 
			
		||||
 | 
			
		||||
            query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql);
 | 
			
		||||
 | 
			
		||||
            query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql);
 | 
			
		||||
 | 
			
		||||
            //<2F><><EFBFBD>û<EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
            query = select.LeftJoin<TestTypeInfo>((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql);
 | 
			
		||||
 | 
			
		||||
            query = select.LeftJoin<TestTypeInfo>((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql);
 | 
			
		||||
 | 
			
		||||
            query = select.LeftJoin<TestTypeInfo>((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql);
 | 
			
		||||
 | 
			
		||||
            //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
            query = select
 | 
			
		||||
                .LeftJoin(a => a.Type.Guid == a.TypeGuid)
 | 
			
		||||
                .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql);
 | 
			
		||||
 | 
			
		||||
            query = select
 | 
			
		||||
                .LeftJoin<TestTypeInfo>((a, a__Type) => a__Type.Guid == a.TypeGuid)
 | 
			
		||||
                .LeftJoin<TestTypeParentInfo>((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql);
 | 
			
		||||
 | 
			
		||||
            //<2F><><EFBFBD>û<EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>b<EFBFBD><62>c<EFBFBD><63><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ
 | 
			
		||||
            var query2 = select.From<TestTypeInfo, TestTypeParentInfo>((s, b, c) => s
 | 
			
		||||
                 .LeftJoin(a => a.TypeGuid == b.Guid)
 | 
			
		||||
                 .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule);
 | 
			
		||||
            sql = query2.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" c ON b.\"PARENTID\" = c.\"ID\"", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON b.\"PARENTID\" = c.\"ID\"", sql);
 | 
			
		||||
 | 
			
		||||
            //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD><CFB6><EFBFBD><EFBFBD>㲻<EFBFBD><E3B2BB>
 | 
			
		||||
            query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"").AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql);
 | 
			
		||||
 | 
			
		||||
            query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }).AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public class TiOtmModel1
 | 
			
		||||
 
 | 
			
		||||
@@ -821,65 +821,66 @@ namespace FreeSql.Tests.Oracle
 | 
			
		||||
 | 
			
		||||
            Func<Type, string, string> tableRule = (type, oldname) =>
 | 
			
		||||
            {
 | 
			
		||||
                if (type == typeof(Topic)) return oldname + "AsTable1";
 | 
			
		||||
                else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2";
 | 
			
		||||
                return oldname + "AsTable";
 | 
			
		||||
                if (oldname.Length > 16) oldname = oldname.Remove(16);
 | 
			
		||||
                if (type == typeof(Topic)) return oldname + "_T1";
 | 
			
		||||
                else if (type == typeof(TestTypeInfo)) return oldname + "_T2";
 | 
			
		||||
                return oldname + "_AT";
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            //<2F><><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>a.Type<70><65>a.Type.Parent <20><><EFBFBD>ǵ<EFBFBD><C7B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
            var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule);
 | 
			
		||||
            var sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql);
 | 
			
		||||
 | 
			
		||||
            query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql);
 | 
			
		||||
 | 
			
		||||
            query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql);
 | 
			
		||||
 | 
			
		||||
            //<2F><><EFBFBD>û<EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
            query = select.LeftJoin<TestTypeInfo>((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql);
 | 
			
		||||
 | 
			
		||||
            query = select.LeftJoin<TestTypeInfo>((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql);
 | 
			
		||||
 | 
			
		||||
            query = select.LeftJoin<TestTypeInfo>((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql);
 | 
			
		||||
 | 
			
		||||
            //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
			
		||||
            query = select
 | 
			
		||||
                .LeftJoin(a => a.Type.Guid == a.TypeGuid)
 | 
			
		||||
                .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql);
 | 
			
		||||
 | 
			
		||||
            query = select
 | 
			
		||||
                .LeftJoin<TestTypeInfo>((a, a__Type) => a__Type.Guid == a.TypeGuid)
 | 
			
		||||
                .LeftJoin<TestTypeParentInfo>((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql);
 | 
			
		||||
 | 
			
		||||
            //<2F><><EFBFBD>û<EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>b<EFBFBD><62>c<EFBFBD><63><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ
 | 
			
		||||
            var query2 = select.From<TestTypeInfo, TestTypeParentInfo>((s, b, c) => s
 | 
			
		||||
                 .LeftJoin(a => a.TypeGuid == b.Guid)
 | 
			
		||||
                 .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule);
 | 
			
		||||
            sql = query2.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFOASTABLE2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFOASTABLE\" c ON b.\"PARENTID\" = c.\"ID\"", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON b.\"PARENTID\" = c.\"ID\"", sql);
 | 
			
		||||
 | 
			
		||||
            //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD><CFB6><EFBFBD><EFBFBD>㲻<EFBFBD><E3B2BB>
 | 
			
		||||
            query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"").AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql);
 | 
			
		||||
 | 
			
		||||
            query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }).AsTable(tableRule);
 | 
			
		||||
            sql = query.ToSql().Replace("\r\n", "");
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22ASTABLE1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql);
 | 
			
		||||
            Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public class TiOtmModel1
 | 
			
		||||
 
 | 
			
		||||
@@ -2355,7 +2355,15 @@
 | 
			
		||||
            <summary>
 | 
			
		||||
            将实体类型集合与数据库对比,返回DDL语句
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="entityTypes"></param>
 | 
			
		||||
            <param name="entityTypes">实体类型</param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ICodeFirst.GetComparisonDDLStatements(System.Type,System.String)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            将实体类型与数据库对比,返回DDL语句(指定表名)
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="entityType">实体类型</param>
 | 
			
		||||
            <param name="tableName">指定表名对比</param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ICodeFirst.SyncStructure``1">
 | 
			
		||||
@@ -2372,6 +2380,14 @@
 | 
			
		||||
            <param name="entityTypes"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ICodeFirst.SyncStructure(System.Type,System.String)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            同步实体类型到数据库(指定表名)
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="entityType">实体类型</param>
 | 
			
		||||
            <param name="tableName">指定表名对比</param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ICodeFirst.GetDbInfo(System.Type)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            根据 System.Type 获取数据库信息
 | 
			
		||||
 
 | 
			
		||||
@@ -44,10 +44,17 @@ namespace FreeSql
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 将实体类型集合与数据库对比,返回DDL语句
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="entityTypes"></param>
 | 
			
		||||
        /// <param name="entityTypes">实体类型</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        string GetComparisonDDLStatements(params Type[] entityTypes);
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 将实体类型与数据库对比,返回DDL语句(指定表名)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="entityType">实体类型</param>
 | 
			
		||||
        /// <param name="tableName">指定表名对比</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        string GetComparisonDDLStatements(Type entityType, string tableName);
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 同步实体类型到数据库
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="TEntity"></typeparam>
 | 
			
		||||
@@ -59,6 +66,13 @@ namespace FreeSql
 | 
			
		||||
        /// <param name="entityTypes"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        bool SyncStructure(params Type[] entityTypes);
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 同步实体类型到数据库(指定表名)
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="entityType">实体类型</param>
 | 
			
		||||
        /// <param name="tableName">指定表名对比</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        bool SyncStructure(Type entityType, string tableName);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 根据 System.Type 获取数据库信息
 | 
			
		||||
 
 | 
			
		||||
@@ -41,18 +41,48 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
        public TableAttribute GetConfigEntity(Type type) => _commonUtils.GetConfigEntity(type);
 | 
			
		||||
        public TableInfo GetTableByEntity(Type type) => _commonUtils.GetTableByEntity(type);
 | 
			
		||||
 | 
			
		||||
        public string GetComparisonDDLStatements<TEntity>() => this.GetComparisonDDLStatements(typeof(TEntity));
 | 
			
		||||
        public abstract string GetComparisonDDLStatements(params Type[] entityTypes);
 | 
			
		||||
        protected string GetTableNameLowerOrUpper(string tableName)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrEmpty(tableName)) return "";
 | 
			
		||||
            if (IsSyncStructureToLower) tableName = tableName.ToLower();
 | 
			
		||||
            if (IsSyncStructureToUpper) tableName = tableName.ToUpper();
 | 
			
		||||
            return tableName;
 | 
			
		||||
        }
 | 
			
		||||
        public string GetComparisonDDLStatements<TEntity>() =>
 | 
			
		||||
            this.GetComparisonDDLStatements((typeof(TEntity), ""));
 | 
			
		||||
        public string GetComparisonDDLStatements(params Type[] entityTypes) => entityTypes == null ? null : 
 | 
			
		||||
            this.GetComparisonDDLStatements(entityTypes.Distinct().Select(a => (a, "")).ToArray());
 | 
			
		||||
        public string GetComparisonDDLStatements(Type entityType, string tableName) =>
 | 
			
		||||
           this.GetComparisonDDLStatements((entityType, GetTableNameLowerOrUpper(tableName)));
 | 
			
		||||
        protected abstract string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects);
 | 
			
		||||
 | 
			
		||||
        static object syncStructureLock = new object();
 | 
			
		||||
        internal ConcurrentDictionary<Type, bool> dicSyced = new ConcurrentDictionary<Type, bool>();
 | 
			
		||||
        public bool SyncStructure<TEntity>() => this.SyncStructure(typeof(TEntity));
 | 
			
		||||
        public bool SyncStructure(params Type[] entityTypes)
 | 
			
		||||
        object _dicSycedLock = new object();
 | 
			
		||||
        Dictionary<Type, ConcurrentDictionary<string, bool>> _dicSynced = new Dictionary<Type, ConcurrentDictionary<string, bool>>();
 | 
			
		||||
        internal ConcurrentDictionary<string, bool> _dicSycedGetOrAdd(Type entityType)
 | 
			
		||||
        {
 | 
			
		||||
            if (entityTypes == null) return false;
 | 
			
		||||
            var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a) == false && GetTableByEntity(a)?.DisableSyncStructure == false).ToArray().Distinct().ToArray();
 | 
			
		||||
            if (syncTypes.Any() == false) return false;
 | 
			
		||||
            var before = new Aop.SyncStructureBeforeEventArgs(entityTypes);
 | 
			
		||||
            if (_dicSynced.TryGetValue(entityType, out var trydic) == false)
 | 
			
		||||
                lock (_dicSycedLock)
 | 
			
		||||
                    if (_dicSynced.TryGetValue(entityType, out trydic) == false)
 | 
			
		||||
                        _dicSynced.Add(entityType, trydic = new ConcurrentDictionary<string, bool>());
 | 
			
		||||
            return trydic;
 | 
			
		||||
        }
 | 
			
		||||
        internal void _dicSycedTryAdd(Type entityType, string tableName = null) =>
 | 
			
		||||
            _dicSycedGetOrAdd(entityType).TryAdd(GetTableNameLowerOrUpper(tableName), true);
 | 
			
		||||
 | 
			
		||||
        public bool SyncStructure<TEntity>() =>
 | 
			
		||||
            this.SyncStructure((typeof(TEntity), ""));
 | 
			
		||||
        public bool SyncStructure(params Type[] entityTypes) => entityTypes == null ? false :
 | 
			
		||||
            this.SyncStructure(entityTypes.Distinct().Select(a => (a, "")).ToArray());
 | 
			
		||||
        public bool SyncStructure(Type entityType, string tableName) =>
 | 
			
		||||
           this.SyncStructure((entityType, GetTableNameLowerOrUpper(tableName)));
 | 
			
		||||
        protected bool SyncStructure(params (Type entityType, string tableName)[] objects)
 | 
			
		||||
        {
 | 
			
		||||
            if (objects == null) return false;
 | 
			
		||||
            (Type entityType, string tableName)[] syncObjects = objects.Where(a => _dicSycedGetOrAdd(a.entityType).ContainsKey(GetTableNameLowerOrUpper(a.tableName)) == false && GetTableByEntity(a.entityType)?.DisableSyncStructure == false)
 | 
			
		||||
                .Select(a => (a.entityType, GetTableNameLowerOrUpper(a.tableName))).ToArray();
 | 
			
		||||
            if (syncObjects.Any() == false) return false;
 | 
			
		||||
            var before = new Aop.SyncStructureBeforeEventArgs(syncObjects.Select(a => a.entityType).ToArray());
 | 
			
		||||
            _orm.Aop.SyncStructureBefore?.Invoke(this, before);
 | 
			
		||||
            Exception exception = null;
 | 
			
		||||
            string ddl = null;
 | 
			
		||||
@@ -60,14 +90,14 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            {
 | 
			
		||||
                lock (syncStructureLock)
 | 
			
		||||
                {
 | 
			
		||||
                    ddl = this.GetComparisonDDLStatements(syncTypes);
 | 
			
		||||
                    ddl = this.GetComparisonDDLStatements(syncObjects);
 | 
			
		||||
                    if (string.IsNullOrEmpty(ddl))
 | 
			
		||||
                    {
 | 
			
		||||
                        foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType, true);
 | 
			
		||||
                        foreach (var syncObject in syncObjects) _dicSycedTryAdd(syncObject.entityType, syncObject.tableName);
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                    var affrows = ExecuteDDLStatements(ddl);
 | 
			
		||||
                    foreach (var syncType in syncTypes) dicSyced.TryAdd(syncType, true);
 | 
			
		||||
                    foreach (var syncObject in syncObjects) _dicSycedTryAdd(syncObject.entityType, syncObject.tableName);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -123,6 +123,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            if (string.IsNullOrEmpty(newname)) return _table.DbName;
 | 
			
		||||
            if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower();
 | 
			
		||||
            if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper();
 | 
			
		||||
            if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table.Type, newname);
 | 
			
		||||
            return newname;
 | 
			
		||||
        }
 | 
			
		||||
        public IDelete<T1> AsTable(Func<string, string> tableRule)
 | 
			
		||||
 
 | 
			
		||||
@@ -393,6 +393,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            if (string.IsNullOrEmpty(newname)) return _table.DbName;
 | 
			
		||||
            if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower();
 | 
			
		||||
            if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper();
 | 
			
		||||
            if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table.Type, newname);
 | 
			
		||||
            return newname;
 | 
			
		||||
        }
 | 
			
		||||
        public IInsert<T1> AsTable(Func<string, string> tableRule)
 | 
			
		||||
 
 | 
			
		||||
@@ -895,6 +895,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
                        {
 | 
			
		||||
                            if (_orm.CodeFirst.IsSyncStructureToLower) name = name.ToLower();
 | 
			
		||||
                            if (_orm.CodeFirst.IsSyncStructureToUpper) name = name.ToUpper();
 | 
			
		||||
                            if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(tb.Table.Type, name);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    dict.Add(tb.Table.Type, name);
 | 
			
		||||
 
 | 
			
		||||
@@ -183,7 +183,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            if (typeof(TReturn) == typeof(T1)) return this as ISelect<TReturn>;
 | 
			
		||||
            _tables[0].Parameter = select.Parameters[0];
 | 
			
		||||
            _selectExpression = select.Body;
 | 
			
		||||
            (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TReturn), true);
 | 
			
		||||
            (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TReturn)); //._dicSyced.TryAdd(typeof(TReturn), true);
 | 
			
		||||
            var ret = _orm.Select<TReturn>();
 | 
			
		||||
            Select0Provider<ISelect<T1>, T1>.CopyData(this, ret, null);
 | 
			
		||||
            return ret;
 | 
			
		||||
@@ -198,7 +198,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            ), SelectTableInfoType.InnerJoin);
 | 
			
		||||
            if (typeof(TResult) == typeof(T1)) return this as ISelect<TResult>;
 | 
			
		||||
            _selectExpression = resultSelector.Body;
 | 
			
		||||
            (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult), true);
 | 
			
		||||
            (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true);
 | 
			
		||||
            var ret = _orm.Select<TResult>() as Select1Provider<TResult>;
 | 
			
		||||
            Select0Provider<ISelect<T1>, T1>.CopyData(this, ret, null);
 | 
			
		||||
            return ret;
 | 
			
		||||
@@ -213,7 +213,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            ), SelectTableInfoType.InnerJoin);
 | 
			
		||||
            if (typeof(TResult) == typeof(T1)) return this as ISelect<TResult>;
 | 
			
		||||
            _selectExpression = resultSelector.Body;
 | 
			
		||||
            (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult), true);
 | 
			
		||||
            (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true);
 | 
			
		||||
            var ret = _orm.Select<TResult>() as Select1Provider<TResult>;
 | 
			
		||||
            Select0Provider<ISelect<T1>, T1>.CopyData(this, ret, null);
 | 
			
		||||
            return ret;
 | 
			
		||||
@@ -245,7 +245,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            }
 | 
			
		||||
            if (typeof(TResult) == typeof(T1)) return this as ISelect<TResult>;
 | 
			
		||||
            _selectExpression = resultSelector.Body;
 | 
			
		||||
            (_orm.CodeFirst as CodeFirstProvider).dicSyced.TryAdd(typeof(TResult), true);
 | 
			
		||||
            (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TResult)); //._dicSyced.TryAdd(typeof(TResult), true);
 | 
			
		||||
            var ret = _orm.Select<TResult>() as Select1Provider<TResult>;
 | 
			
		||||
            Select0Provider<ISelect<T1>, T1>.CopyData(this, ret, null);
 | 
			
		||||
            return ret;
 | 
			
		||||
 
 | 
			
		||||
@@ -515,6 +515,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
			
		||||
            if (string.IsNullOrEmpty(newname)) return _table.DbName;
 | 
			
		||||
            if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower();
 | 
			
		||||
            if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper();
 | 
			
		||||
            if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table.Type, newname);
 | 
			
		||||
            return newname;
 | 
			
		||||
        }
 | 
			
		||||
        public IUpdate<T1> AsTable(Func<string, string> tableRule)
 | 
			
		||||
 
 | 
			
		||||
@@ -82,7 +82,7 @@ namespace FreeSql.MySql
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string GetComparisonDDLStatements(params Type[] entityTypes)
 | 
			
		||||
        protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects)
 | 
			
		||||
        {
 | 
			
		||||
            var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5));
 | 
			
		||||
            var database = conn.Value.Database;
 | 
			
		||||
@@ -106,17 +106,27 @@ namespace FreeSql.MySql
 | 
			
		||||
            var sb = new StringBuilder();
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                foreach (var entityType in entityTypes)
 | 
			
		||||
                foreach (var obj in objects)
 | 
			
		||||
                {
 | 
			
		||||
                    if (sb.Length > 0) sb.Append("\r\n");
 | 
			
		||||
                    var tb = _commonUtils.GetTableByEntity(entityType);
 | 
			
		||||
                    if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移");
 | 
			
		||||
                    if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                    var tb = _commonUtils.GetTableByEntity(obj.entityType);
 | 
			
		||||
                    if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移");
 | 
			
		||||
                    if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                    var tbname = tb.DbName.Split(new[] { '.' }, 2);
 | 
			
		||||
                    if (tbname?.Length == 1) tbname = new[] { database, tbname[0] };
 | 
			
		||||
 | 
			
		||||
                    var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名
 | 
			
		||||
                    if (tboldname?.Length == 1) tboldname = new[] { database, tboldname[0] };
 | 
			
		||||
                    if (string.IsNullOrEmpty(obj.tableName) == false)
 | 
			
		||||
                    {
 | 
			
		||||
                        var tbtmpname = obj.tableName.Split(new[] { '.' }, 2);
 | 
			
		||||
                        if (tbtmpname?.Length == 1) tbtmpname = new[] { database, tbtmpname[0] };
 | 
			
		||||
                        if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1])
 | 
			
		||||
                        {
 | 
			
		||||
                            tbname = tbtmpname;
 | 
			
		||||
                            tboldname = null;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tbname[0])) == null) //创建数据库
 | 
			
		||||
                        sb.Append($"CREATE DATABASE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(" default charset utf8 COLLATE utf8_general_ci;\r\n");
 | 
			
		||||
 
 | 
			
		||||
@@ -89,6 +89,6 @@ namespace FreeSql.Odbc.Default
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string GetComparisonDDLStatements(params Type[] entityTypes) => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能");
 | 
			
		||||
        protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects) => throw new NotImplementedException("FreeSql.Odbc.Default 未实现该功能");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -71,7 +71,7 @@ namespace FreeSql.Odbc.MySql
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string GetComparisonDDLStatements(params Type[] entityTypes)
 | 
			
		||||
        protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects)
 | 
			
		||||
        {
 | 
			
		||||
            var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5));
 | 
			
		||||
            var database = conn.Value.Database;
 | 
			
		||||
@@ -95,17 +95,27 @@ namespace FreeSql.Odbc.MySql
 | 
			
		||||
            var sb = new StringBuilder();
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                foreach (var entityType in entityTypes)
 | 
			
		||||
                foreach (var obj in objects)
 | 
			
		||||
                {
 | 
			
		||||
                    if (sb.Length > 0) sb.Append("\r\n");
 | 
			
		||||
                    var tb = _commonUtils.GetTableByEntity(entityType);
 | 
			
		||||
                    if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移");
 | 
			
		||||
                    if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                    var tb = _commonUtils.GetTableByEntity(obj.entityType);
 | 
			
		||||
                    if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移");
 | 
			
		||||
                    if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                    var tbname = tb.DbName.Split(new[] { '.' }, 2);
 | 
			
		||||
                    if (tbname?.Length == 1) tbname = new[] { database, tbname[0] };
 | 
			
		||||
 | 
			
		||||
                    var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名
 | 
			
		||||
                    if (tboldname?.Length == 1) tboldname = new[] { database, tboldname[0] };
 | 
			
		||||
                    if (string.IsNullOrEmpty(obj.tableName) == false)
 | 
			
		||||
                    {
 | 
			
		||||
                        var tbtmpname = obj.tableName.Split(new[] { '.' }, 2);
 | 
			
		||||
                        if (tbtmpname?.Length == 1) tbtmpname = new[] { database, tbtmpname[0] };
 | 
			
		||||
                        if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1])
 | 
			
		||||
                        {
 | 
			
		||||
                            tbname = tbtmpname;
 | 
			
		||||
                            tboldname = null;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tbname[0])) == null) //创建数据库
 | 
			
		||||
                        sb.Append($"CREATE DATABASE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(" default charset utf8 COLLATE utf8_general_ci;\r\n");
 | 
			
		||||
 
 | 
			
		||||
@@ -75,7 +75,7 @@ namespace FreeSql.Odbc.Oracle
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string GetComparisonDDLStatements(params Type[] entityTypes)
 | 
			
		||||
        protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects)
 | 
			
		||||
        {
 | 
			
		||||
            var userId = (_orm.Ado.MasterPool as OdbcOracleConnectionPool).UserId;
 | 
			
		||||
            var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列:列,表,自增
 | 
			
		||||
@@ -83,18 +83,29 @@ namespace FreeSql.Odbc.Oracle
 | 
			
		||||
 | 
			
		||||
            var sb = new StringBuilder();
 | 
			
		||||
            var sbDeclare = new StringBuilder();
 | 
			
		||||
            foreach (var entityType in entityTypes)
 | 
			
		||||
            foreach (var obj in objects)
 | 
			
		||||
            {
 | 
			
		||||
                if (sb.Length > 0) sb.Append("\r\n");
 | 
			
		||||
                var tb = _commonUtils.GetTableByEntity(entityType);
 | 
			
		||||
                if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移");
 | 
			
		||||
                if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                var tb = _commonUtils.GetTableByEntity(obj.entityType);
 | 
			
		||||
                if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移");
 | 
			
		||||
                if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                var tbname = tb.DbName.Split(new[] { '.' }, 2);
 | 
			
		||||
                if (tbname?.Length == 1) tbname = new[] { userId, tbname[0] };
 | 
			
		||||
 | 
			
		||||
                var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名
 | 
			
		||||
                if (tboldname?.Length == 1) tboldname = new[] { userId, tboldname[0] };
 | 
			
		||||
                var primaryKeyName = (entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name;
 | 
			
		||||
                var primaryKeyName = (obj.entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name;
 | 
			
		||||
                if (string.IsNullOrEmpty(obj.tableName) == false)
 | 
			
		||||
                {
 | 
			
		||||
                    var tbtmpname = obj.tableName.Split(new[] { '.' }, 2);
 | 
			
		||||
                    if (tbtmpname?.Length == 1) tbtmpname = new[] { userId, tbtmpname[0] };
 | 
			
		||||
                    if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1])
 | 
			
		||||
                    {
 | 
			
		||||
                        tbname = tbtmpname;
 | 
			
		||||
                        tboldname = null;
 | 
			
		||||
                        primaryKeyName = null;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys.dba_users where username={0}", tbname[0])) == null) //创建数据库
 | 
			
		||||
                    throw new NotImplementedException($"Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}");
 | 
			
		||||
 
 | 
			
		||||
@@ -79,22 +79,32 @@ namespace FreeSql.Odbc.PostgreSQL
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string GetComparisonDDLStatements(params Type[] entityTypes)
 | 
			
		||||
        protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects)
 | 
			
		||||
        {
 | 
			
		||||
            var sb = new StringBuilder();
 | 
			
		||||
            var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列
 | 
			
		||||
 | 
			
		||||
            foreach (var entityType in entityTypes)
 | 
			
		||||
            foreach (var obj in objects)
 | 
			
		||||
            {
 | 
			
		||||
                if (sb.Length > 0) sb.Append("\r\n");
 | 
			
		||||
                var tb = _commonUtils.GetTableByEntity(entityType);
 | 
			
		||||
                if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移");
 | 
			
		||||
                if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                var tb = _commonUtils.GetTableByEntity(obj.entityType);
 | 
			
		||||
                if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移");
 | 
			
		||||
                if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                var tbname = tb.DbName.Split(new[] { '.' }, 2);
 | 
			
		||||
                if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] };
 | 
			
		||||
 | 
			
		||||
                var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名
 | 
			
		||||
                if (tboldname?.Length == 1) tboldname = new[] { "public", tboldname[0] };
 | 
			
		||||
                if (string.IsNullOrEmpty(obj.tableName) == false)
 | 
			
		||||
                {
 | 
			
		||||
                    var tbtmpname = obj.tableName.Split(new[] { '.' }, 2);
 | 
			
		||||
                    if (tbtmpname?.Length == 1) tbtmpname = new[] { "public", tbtmpname[0] };
 | 
			
		||||
                    if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1])
 | 
			
		||||
                    {
 | 
			
		||||
                        tbname = tbtmpname;
 | 
			
		||||
                        tboldname = null;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (string.Compare(tbname[0], "public", true) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from pg_namespace where nspname={0}", tbname[0])) == null) //创建模式
 | 
			
		||||
                    sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n");
 | 
			
		||||
 
 | 
			
		||||
@@ -103,7 +103,7 @@ ELSE
 | 
			
		||||
    , @level2type = 'COLUMN', @level2name = N'{2}'
 | 
			
		||||
", schema.Replace("'", "''"), table.Replace("'", "''"), column.Replace("'", "''"), comment?.Replace("'", "''") ?? "");
 | 
			
		||||
        }
 | 
			
		||||
        public override string GetComparisonDDLStatements(params Type[] entityTypes)
 | 
			
		||||
        protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects)
 | 
			
		||||
        {
 | 
			
		||||
            var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5));
 | 
			
		||||
            var database = conn.Value.Database;
 | 
			
		||||
@@ -127,12 +127,12 @@ ELSE
 | 
			
		||||
            var sb = new StringBuilder();
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                foreach (var entityType in entityTypes)
 | 
			
		||||
                foreach (var obj in objects)
 | 
			
		||||
                {
 | 
			
		||||
                    if (sb.Length > 0) sb.Append("\r\n");
 | 
			
		||||
                    var tb = _commonUtils.GetTableByEntity(entityType);
 | 
			
		||||
                    if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移");
 | 
			
		||||
                    if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                    var tb = _commonUtils.GetTableByEntity(obj.entityType);
 | 
			
		||||
                    if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移");
 | 
			
		||||
                    if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                    var tbname = tb.DbName.Split(new[] { '.' }, 3);
 | 
			
		||||
                    if (tbname?.Length == 1) tbname = new[] { database, "dbo", tbname[0] };
 | 
			
		||||
                    if (tbname?.Length == 2) tbname = new[] { database, tbname[0], tbname[1] };
 | 
			
		||||
@@ -140,6 +140,17 @@ ELSE
 | 
			
		||||
                    var tboldname = tb.DbOldName?.Split(new[] { '.' }, 3); //旧表名
 | 
			
		||||
                    if (tboldname?.Length == 1) tboldname = new[] { database, "dbo", tboldname[0] };
 | 
			
		||||
                    if (tboldname?.Length == 2) tboldname = new[] { database, tboldname[0], tboldname[1] };
 | 
			
		||||
                    if (string.IsNullOrEmpty(obj.tableName) == false)
 | 
			
		||||
                    {
 | 
			
		||||
                        var tbtmpname = obj.tableName.Split(new[] { '.' }, 3);
 | 
			
		||||
                        if (tbtmpname?.Length == 1) tbtmpname = new[] { database, "dbo", tbtmpname[0] };
 | 
			
		||||
                        if (tbtmpname?.Length == 2) tbtmpname = new[] { database, tbtmpname[0], tbtmpname[1] };
 | 
			
		||||
                        if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1] || tbname[2] != tbtmpname[2])
 | 
			
		||||
                        {
 | 
			
		||||
                            tbname = tbtmpname;
 | 
			
		||||
                            tboldname = null;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, $" select 1 from sys.databases where name='{tbname[0]}'") == null) //创建数据库
 | 
			
		||||
                        ExecuteScalar(database, $"if not exists(select 1 from sys.databases where name='{tbname[0]}')\r\n\tcreate database [{tbname[0]}];");
 | 
			
		||||
 
 | 
			
		||||
@@ -76,7 +76,7 @@ namespace FreeSql.Oracle
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string GetComparisonDDLStatements(params Type[] entityTypes)
 | 
			
		||||
        protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects)
 | 
			
		||||
        {
 | 
			
		||||
            var userId = (_orm.Ado.MasterPool as OracleConnectionPool).UserId;
 | 
			
		||||
            var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列:列,表,自增
 | 
			
		||||
@@ -84,18 +84,29 @@ namespace FreeSql.Oracle
 | 
			
		||||
 | 
			
		||||
            var sb = new StringBuilder();
 | 
			
		||||
            var sbDeclare = new StringBuilder();
 | 
			
		||||
            foreach (var entityType in entityTypes)
 | 
			
		||||
            foreach (var obj in objects)
 | 
			
		||||
            {
 | 
			
		||||
                if (sb.Length > 0) sb.Append("\r\n");
 | 
			
		||||
                var tb = _commonUtils.GetTableByEntity(entityType);
 | 
			
		||||
                if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移");
 | 
			
		||||
                if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                var tb = _commonUtils.GetTableByEntity(obj.entityType);
 | 
			
		||||
                if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移");
 | 
			
		||||
                if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                var tbname = tb.DbName.Split(new[] { '.' }, 2);
 | 
			
		||||
                if (tbname?.Length == 1) tbname = new[] { userId, tbname[0] };
 | 
			
		||||
 | 
			
		||||
                var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名
 | 
			
		||||
                if (tboldname?.Length == 1) tboldname = new[] { userId, tboldname[0] };
 | 
			
		||||
                var primaryKeyName = (entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name;
 | 
			
		||||
                var primaryKeyName = (obj.entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name;
 | 
			
		||||
                if (string.IsNullOrEmpty(obj.tableName) == false)
 | 
			
		||||
                {
 | 
			
		||||
                    var tbtmpname = obj.tableName.Split(new[] { '.' }, 2);
 | 
			
		||||
                    if (tbtmpname?.Length == 1) tbtmpname = new[] { userId, tbtmpname[0] };
 | 
			
		||||
                    if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1])
 | 
			
		||||
                    {
 | 
			
		||||
                        tbname = tbtmpname;
 | 
			
		||||
                        tboldname = null;
 | 
			
		||||
                        primaryKeyName = null;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys.dba_users where username={0}", tbname[0])) == null) //创建数据库
 | 
			
		||||
                    throw new NotImplementedException($"Oracle CodeFirst 不支持代码创建 tablespace 与 schemas {tbname[0]}");
 | 
			
		||||
 
 | 
			
		||||
@@ -117,22 +117,32 @@ namespace FreeSql.PostgreSQL
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string GetComparisonDDLStatements(params Type[] entityTypes)
 | 
			
		||||
        protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects)
 | 
			
		||||
        {
 | 
			
		||||
            var sb = new StringBuilder();
 | 
			
		||||
            var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列
 | 
			
		||||
 | 
			
		||||
            foreach (var entityType in entityTypes)
 | 
			
		||||
            foreach (var obj in objects)
 | 
			
		||||
            {
 | 
			
		||||
                if (sb.Length > 0) sb.Append("\r\n");
 | 
			
		||||
                var tb = _commonUtils.GetTableByEntity(entityType);
 | 
			
		||||
                if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移");
 | 
			
		||||
                if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                var tb = _commonUtils.GetTableByEntity(obj.entityType);
 | 
			
		||||
                if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移");
 | 
			
		||||
                if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                var tbname = tb.DbName.Split(new[] { '.' }, 2);
 | 
			
		||||
                if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] };
 | 
			
		||||
 | 
			
		||||
                var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名
 | 
			
		||||
                if (tboldname?.Length == 1) tboldname = new[] { "public", tboldname[0] };
 | 
			
		||||
                if (string.IsNullOrEmpty(obj.tableName) == false)
 | 
			
		||||
                {
 | 
			
		||||
                    var tbtmpname = obj.tableName.Split(new[] { '.' }, 2);
 | 
			
		||||
                    if (tbtmpname?.Length == 1) tbtmpname = new[] { "public", tbtmpname[0] };
 | 
			
		||||
                    if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1])
 | 
			
		||||
                    {
 | 
			
		||||
                        tbname = tbtmpname;
 | 
			
		||||
                        tboldname = null;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (string.Compare(tbname[0], "public", true) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from pg_namespace where nspname={0}", tbname[0])) == null) //创建模式
 | 
			
		||||
                    sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n");
 | 
			
		||||
 
 | 
			
		||||
@@ -106,7 +106,7 @@ ELSE
 | 
			
		||||
    , @level2type = 'COLUMN', @level2name = N'{2}'
 | 
			
		||||
", schema.Replace("'", "''"), table.Replace("'", "''"), column.Replace("'", "''"), comment?.Replace("'", "''") ?? "");
 | 
			
		||||
        }
 | 
			
		||||
        public override string GetComparisonDDLStatements(params Type[] entityTypes)
 | 
			
		||||
        protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects)
 | 
			
		||||
        {
 | 
			
		||||
            var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5));
 | 
			
		||||
            var database = conn.Value.Database;
 | 
			
		||||
@@ -130,12 +130,12 @@ ELSE
 | 
			
		||||
            var sb = new StringBuilder();
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                foreach (var entityType in entityTypes)
 | 
			
		||||
                foreach (var obj in objects)
 | 
			
		||||
                {
 | 
			
		||||
                    if (sb.Length > 0) sb.Append("\r\n");
 | 
			
		||||
                    var tb = _commonUtils.GetTableByEntity(entityType);
 | 
			
		||||
                    if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移");
 | 
			
		||||
                    if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                    var tb = _commonUtils.GetTableByEntity(obj.entityType);
 | 
			
		||||
                    if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移");
 | 
			
		||||
                    if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                    var tbname = tb.DbName.Split(new[] { '.' }, 3);
 | 
			
		||||
                    if (tbname?.Length == 1) tbname = new[] { database, "dbo", tbname[0] };
 | 
			
		||||
                    if (tbname?.Length == 2) tbname = new[] { database, tbname[0], tbname[1] };
 | 
			
		||||
@@ -143,6 +143,17 @@ ELSE
 | 
			
		||||
                    var tboldname = tb.DbOldName?.Split(new[] { '.' }, 3); //旧表名
 | 
			
		||||
                    if (tboldname?.Length == 1) tboldname = new[] { database, "dbo", tboldname[0] };
 | 
			
		||||
                    if (tboldname?.Length == 2) tboldname = new[] { database, tboldname[0], tboldname[1] };
 | 
			
		||||
                    if (string.IsNullOrEmpty(obj.tableName) == false)
 | 
			
		||||
                    {
 | 
			
		||||
                        var tbtmpname = obj.tableName.Split(new[] { '.' }, 3);
 | 
			
		||||
                        if (tbtmpname?.Length == 1) tbtmpname = new[] { database, "dbo", tbtmpname[0] };
 | 
			
		||||
                        if (tbtmpname?.Length == 2) tbtmpname = new[] { database, tbtmpname[0], tbtmpname[1] };
 | 
			
		||||
                        if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1] || tbname[2] != tbtmpname[2])
 | 
			
		||||
                        {
 | 
			
		||||
                            tbname = tbtmpname;
 | 
			
		||||
                            tboldname = null;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (string.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, $" select 1 from sys.databases where name='{tbname[0]}'") == null) //创建数据库
 | 
			
		||||
                        ExecuteScalar(database, $"if not exists(select 1 from sys.databases where name='{tbname[0]}')\r\n\tcreate database [{tbname[0]}];");
 | 
			
		||||
 
 | 
			
		||||
@@ -73,21 +73,31 @@ namespace FreeSql.Sqlite
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string GetComparisonDDLStatements(params Type[] entityTypes)
 | 
			
		||||
        protected override string GetComparisonDDLStatements(params (Type entityType, string tableName)[] objects)
 | 
			
		||||
        {
 | 
			
		||||
            var sb = new StringBuilder();
 | 
			
		||||
            var sbDeclare = new StringBuilder();
 | 
			
		||||
            foreach (var entityType in entityTypes)
 | 
			
		||||
            foreach (var obj in objects)
 | 
			
		||||
            {
 | 
			
		||||
                if (sb.Length > 0) sb.Append("\r\n");
 | 
			
		||||
                var tb = _commonUtils.GetTableByEntity(entityType);
 | 
			
		||||
                if (tb == null) throw new Exception($"类型 {entityType.FullName} 不可迁移");
 | 
			
		||||
                if (tb.Columns.Any() == false) throw new Exception($"类型 {entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                var tb = _commonUtils.GetTableByEntity(obj.entityType);
 | 
			
		||||
                if (tb == null) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移");
 | 
			
		||||
                if (tb.Columns.Any() == false) throw new Exception($"类型 {obj.entityType.FullName} 不可迁移,可迁移属性0个");
 | 
			
		||||
                var tbname = tb.DbName.Split(new[] { '.' }, 2);
 | 
			
		||||
                if (tbname?.Length == 1) tbname = new[] { "main", tbname[0] };
 | 
			
		||||
 | 
			
		||||
                var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名
 | 
			
		||||
                if (tboldname?.Length == 1) tboldname = new[] { "main", tboldname[0] };
 | 
			
		||||
                if (string.IsNullOrEmpty(obj.tableName) == false)
 | 
			
		||||
                {
 | 
			
		||||
                    var tbtmpname = obj.tableName.Split(new[] { '.' }, 2);
 | 
			
		||||
                    if (tbtmpname?.Length == 1) tbtmpname = new[] { "main", tbtmpname[0] };
 | 
			
		||||
                    if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1])
 | 
			
		||||
                    {
 | 
			
		||||
                        tbname = tbtmpname;
 | 
			
		||||
                        tboldname = null;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                var sbalter = new StringBuilder();
 | 
			
		||||
                var istmpatler = false; //创建临时表,导入数据,删除旧表,修改
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user