From dda7c8bc9cd645b07ca6ca712949be1aebc6f520 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Wed, 13 Nov 2019 19:57:44 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20AsTable=20=E5=92=8C=20?= =?UTF-8?q?Repository=20=E5=88=86=E8=A1=A8=E6=97=B6=E7=9A=84=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E8=BF=81=E7=A7=BB=E5=88=86=E8=A1=A8=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=9B=20-=20=E5=A2=9E=E5=8A=A0=20ICodeFirst.SyncStructure(T?= =?UTF-8?q?ype=20entityType,=20string=20tableName)=20=E6=8C=87=E5=AE=9A?= =?UTF-8?q?=E8=A1=A8=E5=90=8D=E6=9D=A5=E8=BF=81=E7=A7=BB=E5=AE=9E=E4=BD=93?= =?UTF-8?q?=EF=BC=9B=20```csharp=20fsql.CodeFirst.SyncStructure(typeof(Log?= =?UTF-8?q?),=20"Log=5F1");=20//=E8=BF=81=E7=A7=BB=E5=88=B0=20Log=5F1=20?= =?UTF-8?q?=E8=A1=A8=20fsql.CodeFirst.SyncStructure(typeof(Log),=20"Log=5F?= =?UTF-8?q?2");=20//=E8=BF=81=E7=A7=BB=E5=88=B0=20Log=5F2=20=E8=A1=A8=20``?= =?UTF-8?q?`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 7 --- .../Oracle/Curd/OracleSelectTest.cs | 29 +++++----- .../Oracle/Curd/OracleSelectTest.cs | 29 +++++----- FreeSql/FreeSql.xml | 18 ++++++- FreeSql/Interface/ICodeFirst.cs | 16 +++++- .../CommonProvider/CodeFirstProvider.cs | 54 ++++++++++++++----- .../Internal/CommonProvider/DeleteProvider.cs | 1 + .../Internal/CommonProvider/InsertProvider.cs | 1 + .../SelectProvider/Select0Provider.cs | 1 + .../SelectProvider/Select1Provider.cs | 8 +-- .../Internal/CommonProvider/UpdateProvider.cs | 1 + .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 20 +++++-- .../Default/OdbcCodeFirst.cs | 2 +- .../MySql/OdbcMySqlCodeFirst.cs | 20 +++++-- .../Oracle/OdbcOracleCodeFirst.cs | 23 +++++--- .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 20 +++++-- .../SqlServer/OdbcSqlServerCodeFirst.cs | 21 ++++++-- .../OracleCodeFirst.cs | 23 +++++--- .../PostgreSQLCodeFirst.cs | 20 +++++-- .../SqlServerCodeFirst.cs | 21 ++++++-- .../SqliteCodeFirst.cs | 20 +++++-- 21 files changed, 254 insertions(+), 101 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 2711e35d..3f9fb047 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -99,13 +99,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs index 9c9a7d8f..6894291e 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/Curd/OracleSelectTest.cs @@ -821,65 +821,66 @@ namespace FreeSql.Tests.Odbc.Oracle Func 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"; }; //����е�������a.Type��a.Type.Parent ���ǵ������� 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); //���û�е������� query = select.LeftJoin((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((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((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); //������� 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((a, a__Type) => a__Type.Guid == a.TypeGuid) .LeftJoin((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); //���û�е�������b��c������ϵ var query2 = select.From((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); //������϶����㲻�� 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 diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs index 92ecbd0c..2314666d 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/Curd/OracleSelectTest.cs @@ -821,65 +821,66 @@ namespace FreeSql.Tests.Oracle Func 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"; }; //����е�������a.Type��a.Type.Parent ���ǵ������� 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); //���û�е������� query = select.LeftJoin((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((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((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); //������� 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((a, a__Type) => a__Type.Guid == a.TypeGuid) .LeftJoin((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); //���û�е�������b��c������ϵ var query2 = select.From((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); //������϶����㲻�� 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 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 9675d56b..185896b3 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2355,7 +2355,15 @@ 将实体类型集合与数据库对比,返回DDL语句 - + 实体类型 + + + + + 将实体类型与数据库对比,返回DDL语句(指定表名) + + 实体类型 + 指定表名对比 @@ -2372,6 +2380,14 @@ + + + 同步实体类型到数据库(指定表名) + + 实体类型 + 指定表名对比 + + 根据 System.Type 获取数据库信息 diff --git a/FreeSql/Interface/ICodeFirst.cs b/FreeSql/Interface/ICodeFirst.cs index 18b7b67e..e79fe7cc 100644 --- a/FreeSql/Interface/ICodeFirst.cs +++ b/FreeSql/Interface/ICodeFirst.cs @@ -44,10 +44,17 @@ namespace FreeSql /// /// 将实体类型集合与数据库对比,返回DDL语句 /// - /// + /// 实体类型 /// string GetComparisonDDLStatements(params Type[] entityTypes); /// + /// 将实体类型与数据库对比,返回DDL语句(指定表名) + /// + /// 实体类型 + /// 指定表名对比 + /// + string GetComparisonDDLStatements(Type entityType, string tableName); + /// /// 同步实体类型到数据库 /// /// @@ -59,6 +66,13 @@ namespace FreeSql /// /// bool SyncStructure(params Type[] entityTypes); + /// + /// 同步实体类型到数据库(指定表名) + /// + /// 实体类型 + /// 指定表名对比 + /// + bool SyncStructure(Type entityType, string tableName); /// /// 根据 System.Type 获取数据库信息 diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index a71c680a..1f00f176 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -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() => 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() => + 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 dicSyced = new ConcurrentDictionary(); - public bool SyncStructure() => this.SyncStructure(typeof(TEntity)); - public bool SyncStructure(params Type[] entityTypes) + object _dicSycedLock = new object(); + Dictionary> _dicSynced = new Dictionary>(); + internal ConcurrentDictionary _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()); + return trydic; + } + internal void _dicSycedTryAdd(Type entityType, string tableName = null) => + _dicSycedGetOrAdd(entityType).TryAdd(GetTableNameLowerOrUpper(tableName), true); + + public bool SyncStructure() => + 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; } } diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 24c07bad..b1b740af 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -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 AsTable(Func tableRule) diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index d7a95343..e344d149 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -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 AsTable(Func tableRule) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 4859985b..47687449 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -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); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index de88f2a9..96bee31f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -183,7 +183,7 @@ namespace FreeSql.Internal.CommonProvider if (typeof(TReturn) == typeof(T1)) return this as ISelect; _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(); Select0Provider, 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; _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() as Select1Provider; Select0Provider, 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; _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() as Select1Provider; Select0Provider, T1>.CopyData(this, ret, null); return ret; @@ -245,7 +245,7 @@ namespace FreeSql.Internal.CommonProvider } if (typeof(TResult) == typeof(T1)) return this as ISelect; _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() as Select1Provider; Select0Provider, T1>.CopyData(this, ret, null); return ret; diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 44313046..8823c5bc 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -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 AsTable(Func tableRule) diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index 8457e93d..34dae9ea 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -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"); diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs index b007fb41..47098780 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcCodeFirst.cs @@ -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 未实现该功能"); } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index 06effe56..557692e9 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -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"); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index 84394be6..a7fc5be4 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -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]}"); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index 964764a1..2b5c557e 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -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"); diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index f9448e14..d8cd5f74 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -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]}];"); diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 6ac27090..ee4f2097 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -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]}"); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index 961ef8b5..fa57fdf1 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -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"); diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index e9249c2b..bcc14338 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -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]}];"); diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs index 9b00b103..1c665dc7 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteCodeFirst.cs @@ -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; //创建临时表,导入数据,删除旧表,修改