From 2a115ffcfecac907704071387a1648e9b9697ff9 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 25 Dec 2018 12:29:08 +0800 Subject: [PATCH] =?UTF-8?q?CodeFirst=20sqlserver=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=B7=A8=E5=BA=93/=E8=B7=A8schema=E6=94=B9=E8=A1=A8=E5=90=8D?= =?UTF-8?q?=EF=BC=8Cmysql=E6=94=AF=E6=8C=81=E8=B7=A8=E5=BA=93=E6=94=B9?= =?UTF-8?q?=E8=A1=A8=E5=90=8D=EF=BC=8Cpostgresql=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=B7=A8schema=E6=94=B9=E8=A1=A8=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Docs/select.md | 1 - FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs | 144 ++++----- FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 3 +- .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 95 ++++++ .../SqlServer/Curd/SqlServerSelectTest.cs | 144 ++++----- .../SqlServer/SqlServerCodeFirstTest.cs | 1 + FreeSql.Tests/UnitTest1.cs | 13 + FreeSql.Tests/g.cs | 4 + FreeSql/FreeSqlBuilder.cs | 2 +- FreeSql/Interface/Curd/ISelect/ISelect1.cs | 19 +- FreeSql/Interface/Curd/ISelect/ISelect10.cs | 3 - FreeSql/Interface/Curd/ISelect/ISelect2.cs | 3 - FreeSql/Interface/Curd/ISelect/ISelect3.cs | 3 - FreeSql/Interface/Curd/ISelect/ISelect4.cs | 3 - FreeSql/Interface/Curd/ISelect/ISelect5.cs | 3 - FreeSql/Interface/Curd/ISelect/ISelect6.cs | 3 - FreeSql/Interface/Curd/ISelect/ISelect7.cs | 3 - FreeSql/Interface/Curd/ISelect/ISelect8.cs | 3 - FreeSql/Interface/Curd/ISelect/ISelect9.cs | 3 - FreeSql/Interface/Curd/ISelect/ISelectFrom.cs | 17 -- .../Interface/Curd/ISelect/ISelectGrouping.cs | 46 +++ FreeSql/Internal/CommonExpression.cs | 17 +- .../SelectProvider/Select0Provider.cs | 24 +- .../SelectProvider/Select10Provider.cs | 4 - .../SelectProvider/Select1Provider.cs | 13 +- .../SelectProvider/Select2Provider.cs | 4 - .../SelectProvider/Select3Provider.cs | 4 - .../SelectProvider/Select4Provider.cs | 4 - .../SelectProvider/Select5Provider.cs | 4 - .../SelectProvider/Select6Provider.cs | 4 - .../SelectProvider/Select7Provider.cs | 4 - .../SelectProvider/Select8Provider.cs | 4 - .../SelectProvider/Select9Provider.cs | 4 - .../SelectProvider/SelectGroupingProvider.cs | 42 +++ .../Internal/Model/ReadAnonymousTypeInfo.cs | 1 + FreeSql/Internal/Utils.cs | 5 +- FreeSql/MySql/MySqlCodeFirst.cs | 236 ++++++++++----- FreeSql/PostgreSQL/PostgreSQLCodeFirst.cs | 151 +++++++--- FreeSql/PostgreSQL/PostgreSQLExpression.cs | 3 +- FreeSql/PostgreSQL/PostgreSQLProvider.cs | 18 +- FreeSql/PostgreSQL/PostgreSQLUtils.cs | 24 +- FreeSql/SqlServer/SqlServerCodeFirst.cs | 284 ++++++++++-------- readme.md | 213 +++++++------ 43 files changed, 916 insertions(+), 667 deletions(-) create mode 100644 FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs create mode 100644 FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs create mode 100644 FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs diff --git a/Docs/select.md b/Docs/select.md index cc4bd3e4..56ae2b71 100644 --- a/Docs/select.md +++ b/Docs/select.md @@ -188,7 +188,6 @@ List t8 = fsql.Ado.Query("select * from song"); | WhereIf | \ | bool, Lambda | 支持多表查询表达式 | | Where | \ | string, parms | 原生sql语法条件,Where("id = ?id", new { id = 1 }) | | WhereIf | \ | bool, string, parms | 原生sql语法条件,WhereIf(true, "id = ?id", new { id = 1 }) | -| WhereLike | \ | Lambda, string, bool | like 查询条件,where title like '%xxx%' or content like '%xxx%' | | 【分组】 | | GroupBy | \ | Lambda | 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time}) | GroupBy(a => new[]{"name","time"}) | | GroupBy | \ | string, parms | 按原生sql语法分组,GroupBy("concat(name, ?cc)", new { cc = 1 }) | diff --git a/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs index 6d996913..fcf58af3 100644 --- a/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs +++ b/FreeSql.Tests/MySql/Curd/MySqlSelectTest.cs @@ -153,7 +153,7 @@ namespace FreeSql.Tests.MySql { .LeftJoin(a => b.ParentId == c.Id) ); var sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TestTypeInfoGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TestTypeInfoGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); query2.ToList(); } [Fact] @@ -161,33 +161,33 @@ namespace FreeSql.Tests.MySql { //����е�������a.Type��a.Type.Parent ���ǵ������� var query = select.LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid); var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid`", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid`", sql); query.ToList(); query = select.LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` AND a__Type.`Name` = 'xxx'", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` AND a__Type.`Name` = 'xxx'", sql); query.ToList(); query = select.LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON 1 = 1 LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` AND a__Type.`Name` = 'xxx' WHERE (a__Type__Parent.`Id` = 10)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON 1 = 1 LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` AND a__Type.`Name` = 'xxx' WHERE (a__Type__Parent.`Id` = 10)", sql); query.ToList(); //���û�е������� query = select.LeftJoin((a, b) => b.Guid == a.TestTypeInfoGuid); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid`", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid`", sql); query.ToList(); query = select.LeftJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` AND b.`Name` = 'xxx'", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` AND b.`Name` = 'xxx'", sql); query.ToList(); query = select.LeftJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a LEFT JOIN `TestTypeParentInfo` b__Parent ON 1 = 1 LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` AND b.`Name` = 'xxx' WHERE (b__Parent.`Id` = 10)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeParentInfo` b__Parent ON 1 = 1 LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` AND b.`Name` = 'xxx' WHERE (b__Parent.`Id` = 10)", sql); query.ToList(); //������� @@ -195,14 +195,14 @@ namespace FreeSql.Tests.MySql { .LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid) .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); query.ToList(); query = select .LeftJoin((a, b) => b.Guid == a.TestTypeInfoGuid) .LeftJoin((a, c) => c.Id == a.Type.ParentId); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` LEFT JOIN `TestTypeParentInfo` c ON c.`Id` = b.`ParentId`", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` LEFT JOIN `TestTypeParentInfo` c ON c.`Id` = b.`ParentId`", sql); query.ToList(); //���û�е�������b��c������ϵ @@ -210,18 +210,18 @@ namespace FreeSql.Tests.MySql { .LeftJoin(a => a.TestTypeInfoGuid == b.Guid) .LeftJoin(a => b.ParentId == c.Id)); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TestTypeInfoGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TestTypeInfoGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); query2.ToList(); //������϶����㲻�� query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid", sql); query.ToList(); query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = ?bname", new { bname = "xxx" }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = ?bname", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = ?bname", sql); query.ToList(); } [Fact] @@ -229,33 +229,33 @@ namespace FreeSql.Tests.MySql { //����е�������a.Type��a.Type.Parent ���ǵ������� var query = select.InnerJoin(a => a.Type.Guid == a.TestTypeInfoGuid); var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid`", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid`", sql); query.ToList(); query = select.InnerJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` AND a__Type.`Name` = 'xxx'", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` AND a__Type.`Name` = 'xxx'", sql); query.ToList(); query = select.InnerJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON 1 = 1 INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` AND a__Type.`Name` = 'xxx' WHERE (a__Type__Parent.`Id` = 10)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON 1 = 1 INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` AND a__Type.`Name` = 'xxx' WHERE (a__Type__Parent.`Id` = 10)", sql); query.ToList(); //���û�е������� query = select.InnerJoin((a, b) => b.Guid == a.TestTypeInfoGuid); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid`", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid`", sql); query.ToList(); query = select.InnerJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` AND b.`Name` = 'xxx'", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` AND b.`Name` = 'xxx'", sql); query.ToList(); query = select.InnerJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a LEFT JOIN `TestTypeParentInfo` b__Parent ON 1 = 1 INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` AND b.`Name` = 'xxx' WHERE (b__Parent.`Id` = 10)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeParentInfo` b__Parent ON 1 = 1 INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` AND b.`Name` = 'xxx' WHERE (b__Parent.`Id` = 10)", sql); query.ToList(); //������� @@ -263,14 +263,14 @@ namespace FreeSql.Tests.MySql { .InnerJoin(a => a.Type.Guid == a.TestTypeInfoGuid) .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` INNER JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` INNER JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); query.ToList(); query = select .InnerJoin((a, b) => b.Guid == a.TestTypeInfoGuid) .InnerJoin((a, c) => c.Id == a.Type.ParentId); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` INNER JOIN `TestTypeParentInfo` c ON c.`Id` = b.`ParentId`", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` INNER JOIN `TestTypeParentInfo` c ON c.`Id` = b.`ParentId`", sql); query.ToList(); //���û�е�������b��c������ϵ @@ -278,18 +278,18 @@ namespace FreeSql.Tests.MySql { .InnerJoin(a => a.TestTypeInfoGuid == b.Guid) .InnerJoin(a => b.ParentId == c.Id)); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON a.`TestTypeInfoGuid` = b.`Guid` INNER JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON a.`TestTypeInfoGuid` = b.`Guid` INNER JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); query2.ToList(); //������϶����㲻�� query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid", sql); query.ToList(); query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = ?bname", new { bname = "xxx" }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = ?bname", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = ?bname", sql); query.ToList(); } @@ -298,33 +298,33 @@ namespace FreeSql.Tests.MySql { //����е�������a.Type��a.Type.Parent ���ǵ������� var query = select.RightJoin(a => a.Type.Guid == a.TestTypeInfoGuid); var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid`", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid`", sql); query.ToList(); query = select.RightJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` AND a__Type.`Name` = 'xxx'", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` AND a__Type.`Name` = 'xxx'", sql); query.ToList(); query = select.RightJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON 1 = 1 RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` AND a__Type.`Name` = 'xxx' WHERE (a__Type__Parent.`Id` = 10)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON 1 = 1 RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` AND a__Type.`Name` = 'xxx' WHERE (a__Type__Parent.`Id` = 10)", sql); query.ToList(); //���û�е������� query = select.RightJoin((a, b) => b.Guid == a.TestTypeInfoGuid); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid`", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid`", sql); query.ToList(); query = select.RightJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` AND b.`Name` = 'xxx'", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` AND b.`Name` = 'xxx'", sql); query.ToList(); query = select.RightJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a LEFT JOIN `TestTypeParentInfo` b__Parent ON 1 = 1 RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` AND b.`Name` = 'xxx' WHERE (b__Parent.`Id` = 10)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeParentInfo` b__Parent ON 1 = 1 RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` AND b.`Name` = 'xxx' WHERE (b__Parent.`Id` = 10)", sql); query.ToList(); //������� @@ -332,14 +332,14 @@ namespace FreeSql.Tests.MySql { .RightJoin(a => a.Type.Guid == a.TestTypeInfoGuid) .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` RIGHT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TestTypeInfoGuid` RIGHT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); query.ToList(); query = select .RightJoin((a, b) => b.Guid == a.TestTypeInfoGuid) .RightJoin((a, c) => c.Id == a.Type.ParentId); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` RIGHT JOIN `TestTypeParentInfo` c ON c.`Id` = b.`ParentId`", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TestTypeInfoGuid` RIGHT JOIN `TestTypeParentInfo` c ON c.`Id` = b.`ParentId`", sql); query.ToList(); //���û�е�������b��c������ϵ @@ -347,18 +347,18 @@ namespace FreeSql.Tests.MySql { .RightJoin(a => a.TestTypeInfoGuid == b.Guid) .RightJoin(a => b.ParentId == c.Id)); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON a.`TestTypeInfoGuid` = b.`Guid` RIGHT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON a.`TestTypeInfoGuid` = b.`Guid` RIGHT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); query2.ToList(); //������϶����㲻�� query = select.RightJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid", sql); query.ToList(); query = select.RightJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = ?bname", new { bname = "xxx" }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = ?bname", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = ?bname", sql); query.ToList(); } @@ -367,48 +367,48 @@ namespace FreeSql.Tests.MySql { //����е�������a.Type��a.Type.Parent ���ǵ������� var query = select.Where(a => a.Id == 10); var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a WHERE (a.`Id` = 10)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10)", sql); query.ToList(); query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a WHERE (a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100)", sql); query.ToList(); query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a WHERE (a.`Id` = 10) AND (a.`Clicks` > 100)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10) AND (a.`Clicks` > 100)", sql); query.ToList(); query = select.Where(a => a.Type.Name == "typeTitle"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a, `TestTypeInfo` a__Type WHERE (a__Type.`Name` = 'typeTitle')", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` a__Type WHERE (a__Type.`Name` = 'typeTitle')", sql); query.ToList(); query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TestTypeInfoGuid); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a, `TestTypeInfo` a__Type WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TestTypeInfoGuid`)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` a__Type WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TestTypeInfoGuid`)", sql); query.ToList(); query = select.Where(a => a.Type.Parent.Name == "tparent"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a, `TestTypeInfo` a__Type, `TestTypeParentInfo` a__Type__Parent WHERE (a__Type__Parent.`Name` = 'tparent')", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` a__Type, `TestTypeParentInfo` a__Type__Parent WHERE (a__Type__Parent.`Name` = 'tparent')", sql); query.ToList(); //���û�е������ԣ��򵥶������ query = select.Where((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "typeTitle"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Guid` = a.`TestTypeInfoGuid` AND b.`Name` = 'typeTitle')", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Guid` = a.`TestTypeInfoGuid` AND b.`Name` = 'typeTitle')", sql); query.ToList(); query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TestTypeInfoGuid); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Name` = 'typeTitle' AND b.`Guid` = a.`TestTypeInfoGuid`)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Name` = 'typeTitle' AND b.`Guid` = a.`TestTypeInfoGuid`)", sql); query.ToList(); query = select.Where((a, b, c) => c.Name == "tparent"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a, `TestTypeParentInfo` c WHERE (c.`Name` = 'tparent')", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeParentInfo` c WHERE (c.`Name` = 'tparent')", sql); query.ToList(); //����һ�� From ��Ķ������ @@ -416,13 +416,13 @@ namespace FreeSql.Tests.MySql { .Where(a => a.Id == 10 && c.Name == "xxx") .Where(a => b.ParentId == 20)); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a, `TestTypeParentInfo` c, `TestTypeInfo` b WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeParentInfo` c, `TestTypeInfo` b WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); query2.ToList(); //������϶����㲻�� query = select.Where("a.clicks > 100 and a.id = ?id", new { id = 10 }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = ?id)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = ?id)", sql); query.ToList(); } [Fact] @@ -430,32 +430,32 @@ namespace FreeSql.Tests.MySql { //����е�������a.Type��a.Type.Parent ���ǵ������� var query = select.WhereIf(true, a => a.Id == 10); var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a WHERE (a.`Id` = 10)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10)", sql); query.ToList(); query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a WHERE (a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10 AND a.`Id` > 10 OR a.`Clicks` > 100)", sql); query.ToList(); query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a WHERE (a.`Id` = 10) AND (a.`Clicks` > 100)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.`Id` = 10) AND (a.`Clicks` > 100)", sql); query.ToList(); query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a, `TestTypeInfo` a__Type WHERE (a__Type.`Name` = 'typeTitle')", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` a__Type WHERE (a__Type.`Name` = 'typeTitle')", sql); query.ToList(); query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TestTypeInfoGuid); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a, `TestTypeInfo` a__Type WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TestTypeInfoGuid`)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` a__Type WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TestTypeInfoGuid`)", sql); query.ToList(); query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a, `TestTypeInfo` a__Type, `TestTypeParentInfo` a__Type__Parent WHERE (a__Type__Parent.`Name` = 'tparent')", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` a__Type, `TestTypeParentInfo` a__Type__Parent WHERE (a__Type__Parent.`Name` = 'tparent')", sql); query.ToList(); //����һ�� From ��Ķ������ @@ -463,13 +463,13 @@ namespace FreeSql.Tests.MySql { .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") .WhereIf(true, a => b.ParentId == 20)); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, b.`Guid` as4, b.`ParentId` as5, b.`Name` as6, a.`Title` as7, a.`CreateTime` as8 FROM `tb_topic` a, `TestTypeParentInfo` c, `TestTypeInfo` b WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeParentInfo` c, `TestTypeInfo` b WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); query2.ToList(); //������϶����㲻�� query = select.WhereIf(true, "a.clicks > 100 and a.id = ?id", new { id = 10 }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = ?id)", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE (a.clicks > 100 and a.id = ?id)", sql); query.ToList(); // ==========================================WhereIf(false) @@ -477,32 +477,32 @@ namespace FreeSql.Tests.MySql { //����е�������a.Type��a.Type.Parent ���ǵ������� query = select.WhereIf(false, a => a.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); query.ToList(); query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); query.ToList(); query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); query.ToList(); query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); query.ToList(); query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TestTypeInfoGuid); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); query.ToList(); query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); query.ToList(); //����һ�� From ��Ķ������ @@ -510,38 +510,16 @@ namespace FreeSql.Tests.MySql { .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") .WhereIf(false, a => b.ParentId == 20)); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); query2.ToList(); //������϶����㲻�� query = select.WhereIf(false, "a.clicks > 100 and a.id = ?id", new { id = 10 }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a", sql); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TestTypeInfoGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); query.ToList(); } [Fact] - public void WhereLike() { - //ģ����ѯ��WhereLike(a => a.Title, "%sql") - var query = select.Where(a => a.Title.StartsWith("ss")).Where(a => a.Type.Name.Contains("sss")); - var sql = query.ToSql().Replace("\r\n", ""); - - query = select.Where(a => a.Title.EndsWith("ss")); - sql = query.ToSql().Replace("\r\n", ""); - - query = select.Where(a => a.Title.Contains("ss")); - sql = query.ToSql().Replace("\r\n", ""); - - query = select.WhereLike(a => a.Title, "%ss"); - sql = query.ToSql().Replace("\r\n", ""); - - query = select.WhereLike(a => a.Title, "%ss").WhereLike(a => a.Title, "%aa"); - sql = query.ToSql().Replace("\r\n", ""); - - //ģ����ѯ��ѡ������ OR��WhereLike(a => new[] { a.Title, a.Content }, "%sql%") - query = select.WhereLike(a => new[] { a.Title, a.Type.Name, a.Type.Parent.Name }, "%aa"); - sql = query.ToSql().Replace("\r\n", ""); - } - [Fact] public void GroupBy() { } [Fact] diff --git a/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 6f12d47e..c2569ece 100644 --- a/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -15,11 +15,12 @@ namespace FreeSql.Tests.MySql { var id = g.mysql.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); } + [Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")] public class TopicAddField { [Column(IsIdentity = true)] public int? Id { get; set; } - public int name { get; set; } + public string name { get; set; } [Column(DbType = "varchar(200) not null", OldName = "title")] public string title222 { get; set; } = "10"; diff --git a/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs new file mode 100644 index 00000000..6c15bec5 --- /dev/null +++ b/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -0,0 +1,95 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.PostgreSQL { + public class PostgreSQLCodeFirstTest { + + [Fact] + public void AddField() { + var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + g.pgsql.Select(); + + var id = g.pgsql.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + } + + [Table(Name = "TopicAddField", OldName = "ccc.TopicAddField")] + public class TopicAddField { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public string name { get; set; } = "xxx"; + //public int name { get; set; } = 3000; + + //[Column(DbType = "varchar(200) not null", OldName = "title")] + //public string title222 { get; set; } = "333"; + + //[Column(DbType = "varchar(200) not null")] + //public string title222333 { get; set; } = "xxx"; + + //[Column(DbType = "varchar(100) not null", OldName = "title122333aaa")] + //public string titleaaa { get; set; } = "fsdf"; + } + + [Fact] + public void GetComparisonDDLStatements() { + + var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + } + + + [Table(Name = "tb_alltype")] + class TableAllType { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + [Column(Name = "testFieldBool1111")] + public bool testFieldBool { get; set; } + public sbyte testFieldSByte { get; set; } + public short testFieldShort { get; set; } + public int testFieldInt { get; set; } + public long testFieldLong { get; set; } + public byte testFieldByte { get; set; } + public ushort testFieldUShort { get; set; } + public uint testFieldUInt { get; set; } + public ulong testFieldULong { get; set; } + public double testFieldDouble { get; set; } + public float testFieldFloat { get; set; } + public decimal testFieldDecimal { get; set; } + public TimeSpan testFieldTimeSpan { get; set; } + public DateTime testFieldDateTime { get; set; } + public DateTimeOffset testFieldDateTimeOffset { get; set; } + public byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public Guid testFieldGuid { get; set; } + + public bool? testFieldBoolNullable { get; set; } + public sbyte? testFieldSByteNullable { get; set; } + public short? testFieldShortNullable { get; set; } + public int? testFieldIntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? testFieldByteNullable { get; set; } + public ushort? testFieldUShortNullable { get; set; } + public uint? testFieldUIntNullable { get; set; } + public ulong? testFieldULongNullable { get; set; } + public double? testFieldDoubleNullable { get; set; } + public float? testFieldFloatNullable { get; set; } + public decimal? testFieldDecimalNullable { get; set; } + public TimeSpan? testFieldTimeSpanNullable { get; set; } + public DateTime? testFieldDateTimeNullable { get; set; } + public DateTimeOffset? testFieldDateTimeNullableOffset { get; set; } + public Guid? testFieldGuidNullable { get; set; } + + public TableAllTypeEnumType1 testFieldEnum1 { get; set; } + public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } + public TableAllTypeEnumType2 testFieldEnum2 { get; set; } + public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs index ce7d9a2b..838d1426 100644 --- a/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs +++ b/FreeSql.Tests/SqlServer/Curd/SqlServerSelectTest.cs @@ -76,7 +76,7 @@ namespace FreeSql.Tests.SqlServer { .LeftJoin(a => b.ParentId == c.Id) ); var sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TestTypeInfoGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TestTypeInfoGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); query2.ToList(); } [Fact] @@ -84,33 +84,33 @@ namespace FreeSql.Tests.SqlServer { //����е�������a.Type��a.Type.Parent ���ǵ������� var query = select.LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid); var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid]", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid]", sql); query.ToList(); query = select.LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx'", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx'", sql); query.ToList(); query = select.LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON 1 = 1 LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx' WHERE (a__Type__Parent.[Id] = 10)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON 1 = 1 LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx' WHERE (a__Type__Parent.[Id] = 10)", sql); query.ToList(); //���û�е������� query = select.LeftJoin((a, b) => b.Guid == a.TestTypeInfoGuid); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid]", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid]", sql); query.ToList(); query = select.LeftJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx'", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx'", sql); query.ToList(); query = select.LeftJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] b__Parent ON 1 = 1 LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx' WHERE (b__Parent.[Id] = 10)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] b__Parent ON 1 = 1 LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx' WHERE (b__Parent.[Id] = 10)", sql); query.ToList(); //������� @@ -118,14 +118,14 @@ namespace FreeSql.Tests.SqlServer { .LeftJoin(a => a.Type.Guid == a.TestTypeInfoGuid) .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); query.ToList(); query = select .LeftJoin((a, b) => b.Guid == a.TestTypeInfoGuid) .LeftJoin((a, c) => c.Id == a.Type.ParentId); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] LEFT JOIN [TestTypeParentInfo] c ON c.[Id] = b.[ParentId]", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] LEFT JOIN [TestTypeParentInfo] c ON c.[Id] = b.[ParentId]", sql); query.ToList(); //���û�е�������b��c������ϵ @@ -133,18 +133,18 @@ namespace FreeSql.Tests.SqlServer { .LeftJoin(a => a.TestTypeInfoGuid == b.Guid) .LeftJoin(a => b.ParentId == c.Id)); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TestTypeInfoGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TestTypeInfoGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); query2.ToList(); //������϶����㲻�� query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid", sql); query.ToList(); query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = @bname", new { bname = "xxx" }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = @bname", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = @bname", sql); query.ToList(); } [Fact] @@ -152,33 +152,33 @@ namespace FreeSql.Tests.SqlServer { //����е�������a.Type��a.Type.Parent ���ǵ������� var query = select.InnerJoin(a => a.Type.Guid == a.TestTypeInfoGuid); var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid]", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid]", sql); query.ToList(); query = select.InnerJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx'", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx'", sql); query.ToList(); query = select.InnerJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON 1 = 1 INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx' WHERE (a__Type__Parent.[Id] = 10)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON 1 = 1 INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx' WHERE (a__Type__Parent.[Id] = 10)", sql); query.ToList(); //���û�е������� query = select.InnerJoin((a, b) => b.Guid == a.TestTypeInfoGuid); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid]", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid]", sql); query.ToList(); query = select.InnerJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx'", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx'", sql); query.ToList(); query = select.InnerJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] b__Parent ON 1 = 1 INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx' WHERE (b__Parent.[Id] = 10)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] b__Parent ON 1 = 1 INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx' WHERE (b__Parent.[Id] = 10)", sql); query.ToList(); //������� @@ -186,14 +186,14 @@ namespace FreeSql.Tests.SqlServer { .InnerJoin(a => a.Type.Guid == a.TestTypeInfoGuid) .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] INNER JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] INNER JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); query.ToList(); query = select .InnerJoin((a, b) => b.Guid == a.TestTypeInfoGuid) .InnerJoin((a, c) => c.Id == a.Type.ParentId); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] INNER JOIN [TestTypeParentInfo] c ON c.[Id] = b.[ParentId]", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] INNER JOIN [TestTypeParentInfo] c ON c.[Id] = b.[ParentId]", sql); query.ToList(); //���û�е�������b��c������ϵ @@ -201,18 +201,18 @@ namespace FreeSql.Tests.SqlServer { .InnerJoin(a => a.TestTypeInfoGuid == b.Guid) .InnerJoin(a => b.ParentId == c.Id)); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON a.[TestTypeInfoGuid] = b.[Guid] INNER JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON a.[TestTypeInfoGuid] = b.[Guid] INNER JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); query2.ToList(); //������϶����㲻�� query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid", sql); query.ToList(); query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = @bname", new { bname = "xxx" }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = @bname", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = @bname", sql); query.ToList(); } @@ -221,33 +221,33 @@ namespace FreeSql.Tests.SqlServer { //����е�������a.Type��a.Type.Parent ���ǵ������� var query = select.RightJoin(a => a.Type.Guid == a.TestTypeInfoGuid); var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid]", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid]", sql); query.ToList(); query = select.RightJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx'", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx'", sql); query.ToList(); query = select.RightJoin(a => a.Type.Guid == a.TestTypeInfoGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON 1 = 1 RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx' WHERE (a__Type__Parent.[Id] = 10)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON 1 = 1 RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] AND a__Type.[Name] = 'xxx' WHERE (a__Type__Parent.[Id] = 10)", sql); query.ToList(); //���û�е������� query = select.RightJoin((a, b) => b.Guid == a.TestTypeInfoGuid); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid]", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid]", sql); query.ToList(); query = select.RightJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx'", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx'", sql); query.ToList(); query = select.RightJoin((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] b__Parent ON 1 = 1 RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx' WHERE (b__Parent.[Id] = 10)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeParentInfo] b__Parent ON 1 = 1 RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'xxx' WHERE (b__Parent.[Id] = 10)", sql); query.ToList(); //������� @@ -255,14 +255,14 @@ namespace FreeSql.Tests.SqlServer { .RightJoin(a => a.Type.Guid == a.TestTypeInfoGuid) .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] RIGHT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TestTypeInfoGuid] RIGHT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); query.ToList(); query = select .RightJoin((a, b) => b.Guid == a.TestTypeInfoGuid) .RightJoin((a, c) => c.Id == a.Type.ParentId); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] RIGHT JOIN [TestTypeParentInfo] c ON c.[Id] = b.[ParentId]", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TestTypeInfoGuid] RIGHT JOIN [TestTypeParentInfo] c ON c.[Id] = b.[ParentId]", sql); query.ToList(); //���û�е�������b��c������ϵ @@ -270,18 +270,18 @@ namespace FreeSql.Tests.SqlServer { .RightJoin(a => a.TestTypeInfoGuid == b.Guid) .RightJoin(a => b.ParentId == c.Id)); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON a.[TestTypeInfoGuid] = b.[Guid] RIGHT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON a.[TestTypeInfoGuid] = b.[Guid] RIGHT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); query2.ToList(); //������϶����㲻�� query = select.RightJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid", sql); query.ToList(); query = select.RightJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = @bname", new { bname = "xxx" }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = @bname", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = @bname", sql); query.ToList(); } @@ -290,48 +290,48 @@ namespace FreeSql.Tests.SqlServer { //����е�������a.Type��a.Type.Parent ���ǵ������� var query = select.Where(a => a.Id == 10); var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a WHERE (a.[Id] = 10)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10)", sql); query.ToList(); query = select.Where(a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a WHERE (a.[Id] = 10 AND a.[Id] > 10 OR a.[Clicks] > 100)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10 AND a.[Id] > 10 OR a.[Clicks] > 100)", sql); query.ToList(); query = select.Where(a => a.Id == 10).Where(a => a.Clicks > 100); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a WHERE (a.[Id] = 10) AND (a.[Clicks] > 100)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10) AND (a.[Clicks] > 100)", sql); query.ToList(); query = select.Where(a => a.Type.Name == "typeTitle"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeInfo] a__Type WHERE (a__Type.[Name] = 'typeTitle')", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] a__Type WHERE (a__Type.[Name] = 'typeTitle')", sql); query.ToList(); query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TestTypeInfoGuid); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeInfo] a__Type WHERE (a__Type.[Name] = 'typeTitle' AND a__Type.[Guid] = a.[TestTypeInfoGuid])", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] a__Type WHERE (a__Type.[Name] = 'typeTitle' AND a__Type.[Guid] = a.[TestTypeInfoGuid])", sql); query.ToList(); query = select.Where(a => a.Type.Parent.Name == "tparent"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeInfo] a__Type, [TestTypeParentInfo] a__Type__Parent WHERE (a__Type__Parent.[Name] = 'tparent')", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] a__Type, [TestTypeParentInfo] a__Type__Parent WHERE (a__Type__Parent.[Name] = 'tparent')", sql); query.ToList(); //���û�е������ԣ��򵥶������ query = select.Where((a, b) => b.Guid == a.TestTypeInfoGuid && b.Name == "typeTitle"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'typeTitle')", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Guid] = a.[TestTypeInfoGuid] AND b.[Name] = 'typeTitle')", sql); query.ToList(); query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TestTypeInfoGuid); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Name] = 'typeTitle' AND b.[Guid] = a.[TestTypeInfoGuid])", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Name] = 'typeTitle' AND b.[Guid] = a.[TestTypeInfoGuid])", sql); query.ToList(); query = select.Where((a, b, c) => c.Name == "tparent"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a, [TestTypeParentInfo] c WHERE (c.[Name] = 'tparent')", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeParentInfo] c WHERE (c.[Name] = 'tparent')", sql); query.ToList(); //����һ�� From ��Ķ������ @@ -339,13 +339,13 @@ namespace FreeSql.Tests.SqlServer { .Where(a => a.Id == 10 && c.Name == "xxx") .Where(a => b.ParentId == 20)); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeParentInfo] c, [TestTypeInfo] b WHERE (a.[Id] = 10 AND c.[Name] = 'xxx') AND (b.[ParentId] = 20)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeParentInfo] c, [TestTypeInfo] b WHERE (a.[Id] = 10 AND c.[Name] = 'xxx') AND (b.[ParentId] = 20)", sql); query2.ToList(); //������϶����㲻�� query = select.Where("a.clicks > 100 and a.id = @id", new { id = 10 }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = @id)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = @id)", sql); query.ToList(); } [Fact] @@ -353,32 +353,32 @@ namespace FreeSql.Tests.SqlServer { //����е�������a.Type��a.Type.Parent ���ǵ������� var query = select.WhereIf(true, a => a.Id == 10); var sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a WHERE (a.[Id] = 10)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10)", sql); query.ToList(); query = select.WhereIf(true, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a WHERE (a.[Id] = 10 AND a.[Id] > 10 OR a.[Clicks] > 100)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10 AND a.[Id] > 10 OR a.[Clicks] > 100)", sql); query.ToList(); query = select.WhereIf(true, a => a.Id == 10).WhereIf(true, a => a.Clicks > 100); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a WHERE (a.[Id] = 10) AND (a.[Clicks] > 100)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.[Id] = 10) AND (a.[Clicks] > 100)", sql); query.ToList(); query = select.WhereIf(true, a => a.Type.Name == "typeTitle"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeInfo] a__Type WHERE (a__Type.[Name] = 'typeTitle')", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] a__Type WHERE (a__Type.[Name] = 'typeTitle')", sql); query.ToList(); query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TestTypeInfoGuid); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeInfo] a__Type WHERE (a__Type.[Name] = 'typeTitle' AND a__Type.[Guid] = a.[TestTypeInfoGuid])", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] a__Type WHERE (a__Type.[Name] = 'typeTitle' AND a__Type.[Guid] = a.[TestTypeInfoGuid])", sql); query.ToList(); query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a__Type.[Guid] as4, a__Type.[ParentId] as5, a__Type.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeInfo] a__Type, [TestTypeParentInfo] a__Type__Parent WHERE (a__Type__Parent.[Name] = 'tparent')", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] a__Type, [TestTypeParentInfo] a__Type__Parent WHERE (a__Type__Parent.[Name] = 'tparent')", sql); query.ToList(); //����һ�� From ��Ķ������ @@ -386,13 +386,13 @@ namespace FreeSql.Tests.SqlServer { .WhereIf(true, a => a.Id == 10 && c.Name == "xxx") .WhereIf(true, a => b.ParentId == 20)); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, b.[Guid] as4, b.[ParentId] as5, b.[Name] as6, a.[Title] as7, a.[CreateTime] as8 FROM [tb_topic22] a, [TestTypeParentInfo] c, [TestTypeInfo] b WHERE (a.[Id] = 10 AND c.[Name] = 'xxx') AND (b.[ParentId] = 20)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeParentInfo] c, [TestTypeInfo] b WHERE (a.[Id] = 10 AND c.[Name] = 'xxx') AND (b.[ParentId] = 20)", sql); query2.ToList(); //������϶����㲻�� query = select.WhereIf(true, "a.clicks > 100 and a.id = @id", new { id = 10 }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = @id)", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a WHERE (a.clicks > 100 and a.id = @id)", sql); query.ToList(); // ==========================================WhereIf(false) @@ -400,32 +400,32 @@ namespace FreeSql.Tests.SqlServer { //����е�������a.Type��a.Type.Parent ���ǵ������� query = select.WhereIf(false, a => a.Id == 10); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); query.ToList(); query = select.WhereIf(false, a => a.Id == 10 && a.Id > 10 || a.Clicks > 100); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); query.ToList(); query = select.WhereIf(false, a => a.Id == 10).WhereIf(false, a => a.Clicks > 100); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); query.ToList(); query = select.WhereIf(false, a => a.Type.Name == "typeTitle"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); query.ToList(); query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TestTypeInfoGuid); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); query.ToList(); query = select.WhereIf(false, a => a.Type.Parent.Name == "tparent"); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); query.ToList(); //����һ�� From ��Ķ������ @@ -433,38 +433,16 @@ namespace FreeSql.Tests.SqlServer { .WhereIf(false, a => a.Id == 10 && c.Name == "xxx") .WhereIf(false, a => b.ParentId == 20)); sql = query2.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); query2.ToList(); //������϶����㲻�� query = select.WhereIf(false, "a.clicks > 100 and a.id = @id", new { id = 10 }); sql = query.ToSql().Replace("\r\n", ""); - Assert.Equal("SELECT a.[Id] as1, a.[Clicks] as2, a.[TestTypeInfoGuid] as3, a.[Title] as4, a.[CreateTime] as5 FROM [tb_topic22] a", sql); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TestTypeInfoGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); query.ToList(); } [Fact] - public void WhereLike() { - //ģ����ѯ��WhereLike(a => a.Title, "%sql") - var query = select.Where(a => a.Title.StartsWith("ss")).Where(a => a.Type.Name.Contains("sss")); - var sql = query.ToSql().Replace("\r\n", ""); - - query = select.Where(a => a.Title.EndsWith("ss")); - sql = query.ToSql().Replace("\r\n", ""); - - query = select.Where(a => a.Title.Contains("ss")); - sql = query.ToSql().Replace("\r\n", ""); - - query = select.WhereLike(a => a.Title, "%ss"); - sql = query.ToSql().Replace("\r\n", ""); - - query = select.WhereLike(a => a.Title, "%ss").WhereLike(a => a.Title, "%aa"); - sql = query.ToSql().Replace("\r\n", ""); - - //ģ����ѯ��ѡ������ OR��WhereLike(a => new[] { a.Title, a.Content }, "%sql%") - query = select.WhereLike(a => new[] { a.Title, a.Type.Name, a.Type.Parent.Name }, "%aa"); - sql = query.ToSql().Replace("\r\n", ""); - } - [Fact] public void GroupBy() { } [Fact] diff --git a/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs index ea366b52..3c6acaed 100644 --- a/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs +++ b/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs @@ -15,6 +15,7 @@ namespace FreeSql.Tests.SqlServer { var id = g.sqlserver.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); } + [Table(Name = "dbo2.TopicAddField", OldName = "tedb1.dbo.TopicAddField")] public class TopicAddField { [Column(IsIdentity = true)] public int Id { get; set; } diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index feba1bca..1a2f414e 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -3,6 +3,7 @@ using FreeSql; using System; using System.Collections.Generic; using Xunit; +using System.Linq; namespace FreeSql.Tests { public class UnitTest1 { @@ -11,6 +12,18 @@ namespace FreeSql.Tests { [Fact] public void Test1() { + //g.mysql.Select().Where(a => a.Id == 1) + // .GroupBy(a => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + // .Having(a => a.Count() > 2 && a.Avg(a.Key.mod4) > 0 && a.Key.mod4 > 0) + // .OrderBy(a => a.Key.tt2) + // .OrderByDescending(a => a.Count()) + // .ToList(a => new { a.Key.tt2, cou1 = a.Count(), arg1 = a.Avg(a.Key.mod4) }); + + + var sss = new[] { 1, 2, 3 }; + sss.Count(); + + var t1 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); var t2 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); diff --git a/FreeSql.Tests/g.cs b/FreeSql.Tests/g.cs index 471df841..14094593 100644 --- a/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/g.cs @@ -12,4 +12,8 @@ public class g { public static IFreeSql sqlserver = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=cms;Pooling=true;Max Pool Size=10") .Build(); + + public static IFreeSql pgsql = new FreeSql.FreeSqlBuilder() + .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=10") + .Build(); } diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 3a90ea62..d4144865 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -56,7 +56,7 @@ namespace FreeSql { switch(_dataType) { case DataType.MySql: return new MySql.MySqlProvider(_cache, null, _masterConnectionString, _slaveConnectionString, _logger); case DataType.SqlServer: return new SqlServer.SqlServerProvider(_cache, null, _masterConnectionString, _slaveConnectionString, _logger); - case DataType.PostgreSQL: return new MySql.MySqlProvider(_cache, null, _masterConnectionString, _slaveConnectionString, _logger); + case DataType.PostgreSQL: return new PostgreSQL.PostgreSQLProvider(_cache, null, _masterConnectionString, _slaveConnectionString, _logger); } return null; } diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 892df25e..fff7de33 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -189,29 +189,12 @@ namespace FreeSql { /// ISelect Where(Expression> exp) where T2 : class where T3 : class where T4 : class where T5 : class; - /// - /// 模糊查询,选择多个列 OR,WhereLike(a => new[] { a.Title, a.Content }, "%sql%") - /// - /// lambda选择列 - /// 查询内容 - /// not like - /// - ISelect WhereLike(Expression> columns, string pattern, bool notLike = false); - /// - /// 模糊查询,WhereLike(a => a.Title, "%sql") - /// - /// lambda选择列 - /// 查询内容 - /// not like - /// - ISelect WhereLike(Expression> column, string pattern, bool notLike = false); - /// /// 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time}) | GroupBy(a => new[]{"name","time"}) /// /// /// - ISelect GroupBy(Expression> columns); + ISelect GroupBy(Expression> columns); /// /// 按列排序,OrderBy(a => a.Time) diff --git a/FreeSql/Interface/Curd/ISelect/ISelect10.cs b/FreeSql/Interface/Curd/ISelect/ISelect10.cs index 59d6a122..5928fd91 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect10.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect10.cs @@ -15,9 +15,6 @@ namespace FreeSql { ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelect WhereLike(Expression> columns, string pattern, bool notLike = false); - ISelect WhereLike(Expression> column, string pattern, bool notLike = false); - ISelect GroupBy(Expression> columns); ISelect OrderBy(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2.cs b/FreeSql/Interface/Curd/ISelect/ISelect2.cs index 24ab6fa0..3e232c38 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2.cs @@ -15,9 +15,6 @@ namespace FreeSql { ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelect WhereLike(Expression> columns, string pattern, bool notLike = false); - ISelect WhereLike(Expression> column, string pattern, bool notLike = false); - ISelect GroupBy(Expression> columns); ISelect OrderBy(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect3.cs b/FreeSql/Interface/Curd/ISelect/ISelect3.cs index 206c5ee3..a7063f12 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect3.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect3.cs @@ -15,9 +15,6 @@ namespace FreeSql { ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelect WhereLike(Expression> columns, string pattern, bool notLike = false); - ISelect WhereLike(Expression> column, string pattern, bool notLike = false); - ISelect GroupBy(Expression> columns); ISelect OrderBy(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect4.cs b/FreeSql/Interface/Curd/ISelect/ISelect4.cs index 7ad2e68a..526a2a6d 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect4.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect4.cs @@ -15,9 +15,6 @@ namespace FreeSql { ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelect WhereLike(Expression> columns, string pattern, bool notLike = false); - ISelect WhereLike(Expression> column, string pattern, bool notLike = false); - ISelect GroupBy(Expression> columns); ISelect OrderBy(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect5.cs b/FreeSql/Interface/Curd/ISelect/ISelect5.cs index 9786b49d..856259ca 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect5.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect5.cs @@ -15,9 +15,6 @@ namespace FreeSql { ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelect WhereLike(Expression> columns, string pattern, bool notLike = false); - ISelect WhereLike(Expression> column, string pattern, bool notLike = false); - ISelect GroupBy(Expression> columns); ISelect OrderBy(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect6.cs b/FreeSql/Interface/Curd/ISelect/ISelect6.cs index bcfc760c..1a0c864d 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect6.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect6.cs @@ -15,9 +15,6 @@ namespace FreeSql { ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelect WhereLike(Expression> columns, string pattern, bool notLike = false); - ISelect WhereLike(Expression> column, string pattern, bool notLike = false); - ISelect GroupBy(Expression> columns); ISelect OrderBy(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect7.cs b/FreeSql/Interface/Curd/ISelect/ISelect7.cs index f471bded..6590be33 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect7.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect7.cs @@ -15,9 +15,6 @@ namespace FreeSql { ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelect WhereLike(Expression> columns, string pattern, bool notLike = false); - ISelect WhereLike(Expression> column, string pattern, bool notLike = false); - ISelect GroupBy(Expression> columns); ISelect OrderBy(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect8.cs b/FreeSql/Interface/Curd/ISelect/ISelect8.cs index 95b75e85..e56638c5 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect8.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect8.cs @@ -15,9 +15,6 @@ namespace FreeSql { ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelect WhereLike(Expression> columns, string pattern, bool notLike = false); - ISelect WhereLike(Expression> column, string pattern, bool notLike = false); - ISelect GroupBy(Expression> columns); ISelect OrderBy(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelect9.cs b/FreeSql/Interface/Curd/ISelect/ISelect9.cs index 5c1bd101..f11133da 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect9.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect9.cs @@ -15,9 +15,6 @@ namespace FreeSql { ISelect Where(Expression> exp); ISelect WhereIf(bool condition, Expression> exp); - ISelect WhereLike(Expression> columns, string pattern, bool notLike = false); - ISelect WhereLike(Expression> column, string pattern, bool notLike = false); - ISelect GroupBy(Expression> columns); ISelect OrderBy(Expression> column); diff --git a/FreeSql/Interface/Curd/ISelect/ISelectFrom.cs b/FreeSql/Interface/Curd/ISelect/ISelectFrom.cs index 98d60493..4bc2981b 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelectFrom.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelectFrom.cs @@ -23,23 +23,6 @@ namespace FreeSql { /// ISelectFromExpression WhereIf(bool condition, Expression> exp); - /// - /// 模糊查询,选择多个列 OR,WhereLike(a => new[] { a.Title, a.Content }, "%sql%") - /// - /// lambda选择列 - /// 查询内容 - /// not like - /// - ISelectFromExpression WhereLike(Expression> columns, string pattern, bool notLike = false); - /// - /// 模糊查询,WhereLike(a => a.Title, "%sql") - /// - /// lambda选择列 - /// 查询内容 - /// not like - /// - ISelectFromExpression WhereLike(Expression> column, string pattern, bool notLike = false); - /// /// 按选择的列分组,GroupBy(a => a.Name) | GroupBy(a => new{a.Name,a.Time}) | GroupBy(a => new[]{"name","time"}) /// diff --git a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs new file mode 100644 index 00000000..876532f9 --- /dev/null +++ b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql { + public interface ISelectGrouping { + /// + /// 按聚合条件过滤,Where(a => a.Count() > 10) + /// + /// lambda表达式 + /// + ISelectGrouping Having(Expression, bool>> exp); + + /// + /// 按列排序,OrderBy(a => a.Time) + /// + /// + /// + /// + ISelectGrouping OrderBy(Expression, TMember>> column); + /// + /// 按列倒向排序,OrderByDescending(a => a.Time) + /// + /// 列 + /// + ISelectGrouping OrderByDescending(Expression, TMember>> column); + + /// + /// 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 + /// + /// 返回类型 + /// 选择列 + /// + List ToList(Expression, TReturn>> select); + } + + public interface ISelectGroupingAggregate { + T1 Key { get; set; } + int Count(); + T3 Sum(T3 column); + T3 Avg(T3 column); + T3 Max(T3 column); + T3 Min(T3 column); + } +} diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 7dc30e12..f12d622a 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -19,15 +19,18 @@ namespace FreeSql.Internal { case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body); case ExpressionType.Negate: case ExpressionType.NegateChecked: - field.Append(", ").Append(ExpressionLambdaToSql(exp, _tables, null, SelectTableInfoType.From, true)).Append(" as").Append(++index); + parent.DbField = $"-{ExpressionLambdaToSql(exp, _tables, null, SelectTableInfoType.From, true)}"; + field.Append(", ").Append(parent.DbField).Append(" as").Append(++index); return false; case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand); case ExpressionType.Constant: var constExp = exp as ConstantExpression; - field.Append(", ").Append(constExp?.Value).Append(" as").Append(++index); + parent.DbField = _common.FormatSql("{0}", constExp?.Value); + field.Append(", ").Append(parent.DbField).Append(" as").Append(++index); return false; case ExpressionType.Call: - field.Append(", ").Append(ExpressionLambdaToSql(exp, _tables, null, SelectTableInfoType.From, true)).Append(" as").Append(++index); + parent.DbField = ExpressionLambdaToSql(exp, _tables, null, SelectTableInfoType.From, true); + field.Append(", ").Append(parent.DbField).Append(" as").Append(++index); return false; case ExpressionType.MemberAccess: if (_common.GetTableByEntity(exp.Type) != null) { //加载表所有字段 @@ -36,11 +39,13 @@ namespace FreeSql.Internal { parent.Consturctor = map.First().Table.Table.Type.GetConstructor(new Type[0]); parent.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties; for (var idx = 0; idx < map.Count; idx++) { - field.Append(", ").Append(map[idx].Table.Alias).Append(".").Append(_common.QuoteSqlName(map[idx].Column.Attribute.Name)).Append(" as").Append(++index); - parent.Childs.Add(new ReadAnonymousTypeInfo { CsName = map[idx].Column.CsName }); + var child = new ReadAnonymousTypeInfo { CsName = map[idx].Column.CsName, DbField = $"{map[idx].Table.Alias}.{_common.QuoteSqlName(map[idx].Column.Attribute.Name)}" }; + field.Append(", ").Append(child.DbField).Append(" as").Append(++index); + parent.Childs.Add(child); } } else { - field.Append(", ").Append(ExpressionLambdaToSql(exp, _tables, null, SelectTableInfoType.From, true)).Append(" as").Append(++index); + parent.DbField = ExpressionLambdaToSql(exp, _tables, null, SelectTableInfoType.From, true); + field.Append(", ").Append(parent.DbField).Append(" as").Append(++index); return false; } return false; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index fbab032e..b4bca5be 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -16,7 +16,7 @@ namespace FreeSql.Internal.CommonProvider { protected string _select = "SELECT ", _orderby, _groupby, _having; protected StringBuilder _where = new StringBuilder(); protected List _params = new List(); - protected List _tables = new List(); + internal List _tables = new List(); protected StringBuilder _join = new StringBuilder(); protected (int seconds, string key) _cache = (0, null); protected IFreeSql _orm; @@ -227,7 +227,9 @@ namespace FreeSql.Internal.CommonProvider { protected TMember InternalMin(Expression exp) => this.ToList($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true)})").FirstOrDefault(); protected TMember InternalSum(Expression exp) => this.ToList($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true)})").FirstOrDefault(); - protected TSelect InternalGroupBy(Expression columns) => this.GroupBy(string.Join(", ", _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, columns, true))); + protected TSelect InternalGroupBy(Expression columns) { + return this.GroupBy(string.Join(", ", _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, columns, true))); + } protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) { _commonExpression.ExpressionJoinLambda(_tables, joinType, exp); return this as TSelect; @@ -245,24 +247,6 @@ namespace FreeSql.Internal.CommonProvider { protected List InternalToList(Expression select) => this.ToList(this.GetNewExpressionField(select as NewExpression)); protected TSelect InternalWhere(Expression exp) => this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp)); - protected TSelect InternalWhereLikeOr(Expression columns, string pattern, bool notLike) { - if (string.IsNullOrEmpty(pattern)) return this as TSelect; - var cols = _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, columns, true); - if (cols.Any() == false) return this as TSelect; - var filter = ""; - foreach (var col in cols) { - if (string.IsNullOrEmpty(col)) continue; - filter += string.Concat(" OR ", _commonUtils.FormatSql($"{col} {(notLike ? "NOT LIKE" : "LIKE")} {{0}}", pattern)); - } - if (string.IsNullOrEmpty(filter)) return this as TSelect; - return this.Where(filter.Substring(4)); - } - protected TSelect InternalWhereLike(Expression column, string pattern, bool notLike) { - if (string.IsNullOrEmpty(pattern)) return this as TSelect; - string col = _commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true); - if (string.IsNullOrEmpty(col)) return this as TSelect; - return this.Where(_commonUtils.FormatSql($"{col} {(notLike ? "NOT LIKE" : "LIKE")} {{0}}", pattern)); - } protected TSelect InternalJoin(Expression exp) { return this as TSelect; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs index 01ef7649..98547b2a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select10Provider.cs @@ -39,9 +39,5 @@ namespace FreeSql.Internal.CommonProvider { ISelect ISelect.Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)); ISelect ISelect.WhereIf(bool condition, Expression> exp) => condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)) : this; - - ISelect ISelect.WhereLike(Expression> columns, string pattern, bool notLike) => this.InternalWhereLikeOr(columns?.Body, pattern, notLike); - - ISelect ISelect.WhereLike(Expression> column, string pattern, bool notLike) => this.InternalWhereLike(column?.Body, pattern, notLike); } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index c6e5de93..9b29fd01 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -29,13 +29,6 @@ namespace FreeSql.Internal.CommonProvider { if (_commonExpression.ExpressionSelectColumn_MemberAccess(null, null, SelectTableInfoType.From, expCall.Arguments[0], false) == "1") this.InternalWhere(expCall.Arguments[1]); break; - case "WhereLike": - var whereLikeArg0 = (expCall.Arguments[0] as UnaryExpression).Operand as LambdaExpression; - var whereLikeArg1 = _commonExpression.ExpressionSelectColumn_MemberAccess(null, null, SelectTableInfoType.From, expCall.Arguments[1], false); - var whereLikeArg2 = _commonExpression.ExpressionSelectColumn_MemberAccess(null, null, SelectTableInfoType.From, expCall.Arguments[2], false) == "1"; - if (whereLikeArg0.ReturnType == typeof(string)) this.InternalWhereLike(whereLikeArg0, whereLikeArg1, whereLikeArg2); - else this.InternalWhereLikeOr(whereLikeArg0, whereLikeArg1, whereLikeArg2); - break; case "GroupBy": this.InternalGroupBy(expCall.Arguments[0]); break; case "OrderBy": this.InternalOrderBy(expCall.Arguments[0]); break; case "OrderByDescending": this.InternalOrderByDescending(expCall.Arguments[0]); break; @@ -80,7 +73,7 @@ namespace FreeSql.Internal.CommonProvider { public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class;// { this.InternalFrom(exp?.Body); var ret = new Select10Provider(_orm, _commonUtils, _commonExpression, null); Select0Provider, T1>.CopyData(this, ret); return ret; } - public ISelect GroupBy(Expression> columns) => this.InternalGroupBy(columns?.Body); + public ISelect GroupBy(Expression> columns) => this.InternalGroupBy(columns?.Body); public TMember Max(Expression> column) => this.InternalMax(column?.Body); @@ -105,9 +98,5 @@ namespace FreeSql.Internal.CommonProvider { public ISelect Where(Expression> exp) where T2 : class where T3 : class where T4 : class where T5 : class => this.InternalWhere(exp?.Body); public ISelect WhereIf(bool condition, Expression> exp) => condition ? this.InternalWhere(exp?.Body) : this; - - public ISelect WhereLike(Expression> columns, string pattern, bool notLike) => this.InternalWhereLikeOr(columns?.Body, pattern, notLike); - - public ISelect WhereLike(Expression> column, string pattern, bool notLike) => this.InternalWhereLike(column?.Body, pattern, notLike); } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs index 1fa78873..630e3b4a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select2Provider.cs @@ -31,9 +31,5 @@ namespace FreeSql.Internal.CommonProvider { ISelect ISelect.Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)); ISelect ISelect.WhereIf(bool condition, Expression> exp) => condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)) : this; - - ISelect ISelect.WhereLike(Expression> columns, string pattern, bool notLike) => this.InternalWhereLikeOr(columns?.Body, pattern, notLike); - - ISelect ISelect.WhereLike(Expression> column, string pattern, bool notLike) => this.InternalWhereLike(column?.Body, pattern, notLike); } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs index 1380feab..14fb6ef1 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select3Provider.cs @@ -32,9 +32,5 @@ namespace FreeSql.Internal.CommonProvider { ISelect ISelect.Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)); ISelect ISelect.WhereIf(bool condition, Expression> exp) => condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)) : this; - - ISelect ISelect.WhereLike(Expression> columns, string pattern, bool notLike) => this.InternalWhereLikeOr(columns?.Body, pattern, notLike); - - ISelect ISelect.WhereLike(Expression> column, string pattern, bool notLike) => this.InternalWhereLike(column?.Body, pattern, notLike); } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs index bd9faf34..8bb92273 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select4Provider.cs @@ -33,9 +33,5 @@ namespace FreeSql.Internal.CommonProvider { ISelect ISelect.Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)); ISelect ISelect.WhereIf(bool condition, Expression> exp) => condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)) : this; - - ISelect ISelect.WhereLike(Expression> columns, string pattern, bool notLike) => this.InternalWhereLikeOr(columns?.Body, pattern, notLike); - - ISelect ISelect.WhereLike(Expression> column, string pattern, bool notLike) => this.InternalWhereLike(column?.Body, pattern, notLike); } } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs index b61789ae..36062060 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select5Provider.cs @@ -34,9 +34,5 @@ namespace FreeSql.Internal.CommonProvider { ISelect ISelect.Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)); ISelect ISelect.WhereIf(bool condition, Expression> exp) => condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)) : this; - - ISelect ISelect.WhereLike(Expression> columns, string pattern, bool notLike) => this.InternalWhereLikeOr(columns?.Body, pattern, notLike); - - ISelect ISelect.WhereLike(Expression> column, string pattern, bool notLike) => this.InternalWhereLike(column?.Body, pattern, notLike); } } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs index 8466a6f3..73c6a295 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select6Provider.cs @@ -35,9 +35,5 @@ namespace FreeSql.Internal.CommonProvider { ISelect ISelect.Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)); ISelect ISelect.WhereIf(bool condition, Expression> exp) => condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)) : this; - - ISelect ISelect.WhereLike(Expression> columns, string pattern, bool notLike) => this.InternalWhereLikeOr(columns?.Body, pattern, notLike); - - ISelect ISelect.WhereLike(Expression> column, string pattern, bool notLike) => this.InternalWhereLike(column?.Body, pattern, notLike); } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs index 6d552002..2da30e2e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select7Provider.cs @@ -36,9 +36,5 @@ namespace FreeSql.Internal.CommonProvider { ISelect ISelect.Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)); ISelect ISelect.WhereIf(bool condition, Expression> exp) => condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)) : this; - - ISelect ISelect.WhereLike(Expression> columns, string pattern, bool notLike) => this.InternalWhereLikeOr(columns?.Body, pattern, notLike); - - ISelect ISelect.WhereLike(Expression> column, string pattern, bool notLike) => this.InternalWhereLike(column?.Body, pattern, notLike); } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs index eb09f9bd..c0ef0b26 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select8Provider.cs @@ -37,9 +37,5 @@ namespace FreeSql.Internal.CommonProvider { ISelect ISelect.Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)); ISelect ISelect.WhereIf(bool condition, Expression> exp) => condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)) : this; - - ISelect ISelect.WhereLike(Expression> columns, string pattern, bool notLike) => this.InternalWhereLikeOr(columns?.Body, pattern, notLike); - - ISelect ISelect.WhereLike(Expression> column, string pattern, bool notLike) => this.InternalWhereLike(column?.Body, pattern, notLike); } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs index 5cdfcd8c..1df87e3b 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select9Provider.cs @@ -38,9 +38,5 @@ namespace FreeSql.Internal.CommonProvider { ISelect ISelect.Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)); ISelect ISelect.WhereIf(bool condition, Expression> exp) => condition ? this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp?.Body)) : this; - - ISelect ISelect.WhereLike(Expression> columns, string pattern, bool notLike) => this.InternalWhereLikeOr(columns?.Body, pattern, notLike); - - ISelect ISelect.WhereLike(Expression> column, string pattern, bool notLike) => this.InternalWhereLike(column?.Body, pattern, notLike); } } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs new file mode 100644 index 00000000..ff60992d --- /dev/null +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -0,0 +1,42 @@ +//using FreeSql.Internal.Model; +//using System; +//using System.Collections.Generic; +//using System.Linq.Expressions; +//using System.Text; + +//namespace FreeSql.Internal.CommonProvider { +// public class SelectGroupingProvider : ISelectGrouping where T2 : class { + +// internal Select1Provider _select; +// internal ReadAnonymousTypeInfo _map; +// internal CommonExpression _comonExp; +// internal SelectTableInfo _table; +// SelectGroupingProvider(CommonExpression comonExp, Expression exp) { +// _comonExp = comonExp; +// //var columns = _comonExp.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_select._tables, columns, true); +// _table = new SelectTableInfo { Alias = "", On = "", Table = _comonExp._common.GetTableByEntity(typeof(T1)), Type = SelectTableInfoType.From }; +// } + +// public ISelectGrouping Having(Expression, bool>> exp) { +// _select.Having(_comonExp.ExpressionWhereLambda(new List(new[] { _table }), exp)); +// return this; +// } + +// public ISelectGrouping OrderBy(Expression, TMember>> column) { +// var columnMap = new List(); +// _comonExp.ExpressionSelectColumn_MemberAccess(new List(new[] { _table }), columnMap, SelectTableInfoType.From, column, true); + +// _select.OrderBy(); +// return this; +// } + +// public ISelectGrouping OrderByDescending(Expression, TMember>> column) { +// _select.OrderBy(" DESC"); +// return this; +// } + +// public List ToList(Expression, TReturn>> select) { +// throw new NotImplementedException(); +// } +// } +//} diff --git a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs index 53ed0894..743d3646 100644 --- a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs +++ b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs @@ -7,6 +7,7 @@ namespace FreeSql.Internal.Model { class ReadAnonymousTypeInfo { public string CsName { get; set; } public Type CsType { get; set; } + public string DbField { get; set; } public ConstructorInfo Consturctor { get; set; } public ReadAnonymousTypeInfoConsturctorType ConsturctorType { get; set; } public List Childs = new List(); diff --git a/FreeSql/Internal/Utils.cs b/FreeSql/Internal/Utils.cs index c0f1d6f4..ee940f4e 100644 --- a/FreeSql/Internal/Utils.cs +++ b/FreeSql/Internal/Utils.cs @@ -48,7 +48,10 @@ namespace FreeSql.Internal { colattr.DbType = Regex.Replace(colattr.DbType, @"\([^\)]+\)", m => Regex.Replace(m.Groups[0].Value, @"\s", "")); colattr.DbDefautValue = trytb.Properties[p.Name].GetValue(Activator.CreateInstance(trytb.Type)); if (colattr.DbDefautValue == null && p.PropertyType.FullName == "System.String") colattr.DbDefautValue = string.Empty; - if (colattr.DbDefautValue == null) colattr.DbDefautValue = Activator.CreateInstance(p.PropertyType.GenericTypeArguments.FirstOrDefault() ?? p.PropertyType); + if (colattr.DbDefautValue == null) { + var consturctorType = p.PropertyType.GenericTypeArguments.FirstOrDefault() ?? p.PropertyType; + if (consturctorType.GetConstructor(new Type[0]) != null) colattr.DbDefautValue = Activator.CreateInstance(consturctorType); + } if (colattr.DbDefautValue == null) colattr.DbDefautValue = ""; if (colattr.DbDefautValue.GetType().FullName == "System.DateTime") colattr.DbDefautValue = new DateTime(1970, 1, 1); diff --git a/FreeSql/MySql/MySqlCodeFirst.cs b/FreeSql/MySql/MySqlCodeFirst.cs index 8c36f480..0f89e4a9 100644 --- a/FreeSql/MySql/MySqlCodeFirst.cs +++ b/FreeSql/MySql/MySqlCodeFirst.cs @@ -80,94 +80,178 @@ namespace FreeSql.MySql { public string GetComparisonDDLStatements() => this.GetComparisonDDLStatements(typeof(TEntity)); public string GetComparisonDDLStatements(params Type[] entityTypes) { - string database = ""; - using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) { - database = conn.Value.Database; - } - var sb = new StringBuilder(); - foreach (var entityType in entityTypes) { - if (sb.Length > 0) sb.Append("\r\n"); - var tb = _commonUtils.GetTableByEntity(entityType); - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 - if (tboldname?.Length == 1) tboldname = new[] { database, tboldname[0] }; - - var isRenameTable = false; - var tbname = tb.DbName.Split(new[] { '.' }, 2); - if (tbname.Length == 1) tbname = new[] { database, tbname[0] }; - if (_orm.Ado.ExecuteScalar(CommandType.Text, "SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}".FormatMySql(tbname)) == null) { //表不存在 - - if (tboldname != null && _orm.Ado.ExecuteScalar(CommandType.Text, "SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}".FormatMySql(tboldname)) != null) { //旧表存在 - //修改表名 - sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); - isRenameTable = true; - - } else { - //创建表 - sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ("); - foreach (var tbcol in tb.Columns.Values) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); - sb.Append(","); - } - if (tb.Primarys.Any() == false) - sb.Remove(sb.Length - 1, 1); - else { - sb.Append(" \r\n PRIMARY KEY ("); - foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); - sb.Remove(sb.Length - 2, 2).Append(")"); - } - sb.Append("\r\n) Engine=InnoDB CHARACTER SET utf8;\r\n"); - continue; + var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); + var database = conn.Value.Database; + Func ExecuteScalar = (db, sql) => { + if (string.Compare(database, db) != 0) try { conn.Value.ChangeDatabase(db); } catch { } + try { + using (var cmd = conn.Value.CreateCommand()) { + cmd.CommandText = sql; + cmd.CommandType = CommandType.Text; + return cmd.ExecuteScalar(); } + } finally { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); } - //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 - var addcols = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - foreach (var tbcol in tb.Columns) addcols.Add(tbcol.Value.Attribute.Name, tbcol.Value); - var surplus = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - var dbcols = new List(); - var sql = @"select + }; + var sb = new StringBuilder(); + try { + foreach (var entityType in entityTypes) { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(entityType); + 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.Compare(tbname[0], database, true) != 0 && ExecuteScalar(database, $"select 1 from pg_database where datname='{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"); + + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (ExecuteScalar(tbname[0], "SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}".FormatMySql(tbname)) == null) { //表不存在 + if (tboldname != null) { + if (string.Compare(tboldname[0], tbname[0], true) != 0 && ExecuteScalar(database, $"select 1 from information_schema.schemata where schema_name='{tboldname[0]}'") == null || + ExecuteScalar(tboldname[0], "SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}".FormatMySql(tboldname)) == null) + //数据库或模式或表不存在 + tboldname = null; + } + if (tboldname == null) { + //创建表 + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ("); + foreach (var tbcol in tb.Columns.Values) { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); + sb.Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); + sb.Append(","); + } + if (tb.Primarys.Any() == false) + sb.Remove(sb.Length - 1, 1); + else { + sb.Append(" \r\n PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")"); + } + sb.Append("\r\n) Engine=InnoDB CHARACTER SET utf8;\r\n"); + continue; + } + //如果新表,旧表在一个数据库下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); + else { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } else + tboldname = null; //如果新表已经存在,不走改表名逻辑 + + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var addcols = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + foreach (var tbcol in tb.Columns) addcols.Add(tbcol.Value.Attribute.Name, tbcol.Value); + var surplus = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + var dbcols = new List(); + var sql = @"select a.column_name, a.column_type, case when a.is_nullable = 'YES' then 1 else 0 end 'is_nullable', case when locate('auto_increment', a.extra) > 0 then 1 else 0 end 'is_identity' from information_schema.columns a -where a.table_schema in ({0}) and a.table_name in ({1})".FormatMySql(isRenameTable ? tboldname : tbname); - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - foreach (var row in ds) { - string column = string.Concat(row[0]); - string sqlType = string.Concat(row[1]); - bool is_nullable = string.Concat(row[2]) == "1"; - bool is_identity = string.Concat(row[3]) == "1"; - bool is_unsigned = sqlType.EndsWith(" unsigned"); +where a.table_schema in ({0}) and a.table_name in ({1})".FormatMySql(tboldname ?? tbname); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => new { + column = string.Concat(a[0]), + sqlType = string.Concat(a[1]), + is_nullable = string.Concat(a[2]) == "1", + is_identity = string.Concat(a[3]) == "1", + is_unsigned = string.Concat(a[1]).EndsWith(" unsigned") + }, StringComparer.CurrentCultureIgnoreCase); - if (addcols.TryGetValue(column, out var trycol)) { - if ((trycol.Attribute.DbType.IndexOf(" unsigned", StringComparison.CurrentCultureIgnoreCase) != -1) != is_unsigned || - trycol.Attribute.DbType.StartsWith(sqlType, StringComparison.CurrentCultureIgnoreCase) == false || - trycol.Attribute.IsNullable != is_nullable || - trycol.Attribute.IsIdentity != is_identity) { - sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(column)).Append(" ").Append(trycol.Attribute.DbType); - if (trycol.Attribute.IsIdentity && trycol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); - sb.Append(";\r\n"); + if (istmpatler == false) { + foreach (var tbcol in tb.Columns.Values) { + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { + if ((tbcol.Attribute.DbType.IndexOf(" unsigned", StringComparison.CurrentCultureIgnoreCase) != -1) != tbstructcol.is_unsigned || + tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || + tbcol.Attribute.IsNullable != tbstructcol.is_nullable || + tbcol.Attribute.IsIdentity != tbstructcol.is_identity) { + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" AUTO_INCREMENT"); + sbalter.Append(";\r\n"); + } + if (tbstructcol.column == tbcol.Attribute.OldName) { + //修改列名 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" CHANGE COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.OldName)).Append(" ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); + sbalter.Append(";\r\n"); + } + continue; + } + //添加列 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" AUTO_INCREMENT"); + sbalter.Append(";\r\n"); } - addcols.Remove(column); - } else - surplus.Add(column, true); //记录剩余字段 - } - foreach (var addcol in addcols.Values) { - if (string.IsNullOrEmpty(addcol.Attribute.OldName) == false && surplus.ContainsKey(addcol.Attribute.OldName)) { //修改列名 - sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" CHANGE COLUMN ").Append(_commonUtils.QuoteSqlName(addcol.Attribute.OldName)).Append(" ").Append(_commonUtils.QuoteSqlName(addcol.Attribute.Name)).Append(" ").Append(addcol.Attribute.DbType); - if (addcol.Attribute.IsIdentity && addcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); - sb.Append(";\r\n"); - - } else { //添加列 - sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(addcol.Attribute.Name)).Append(" ").Append(addcol.Attribute.DbType); - if (addcol.Attribute.IsIdentity && addcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); - sb.Append(";\r\n"); } + if (istmpatler == false) { + sb.Append(sbalter); + continue; + } + + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}"); + //创建临时表 + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.Columns.Values) { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); + sb.Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); + sb.Append(","); + } + if (tb.Primarys.Any() == false) + sb.Remove(sb.Length - 1, 1); + else { + sb.Append(" \r\n PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")"); + } + sb.Append("\r\n) Engine=InnoDB CHARACTER SET utf8;\r\n"); + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.Columns.Values) { + if (tbstruct.ContainsKey(tbcol.Attribute.Name) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.ContainsKey(tbcol.Attribute.OldName)) { //导入旧表存在的字段 + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + } + } + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.Columns.Values) { + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { + var insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) { + //var tbcoldbtype = tbcol.Attribute.DbType.Split(' ').First(); + //insertvalue = $"cast({insertvalue} as {tbcoldbtype})"; + } + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { + insertvalue = $"ifnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")})"; + } + sb.Append(insertvalue).Append(", "); + } + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); + sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); + } + return sb.Length == 0 ? null : sb.ToString(); + } finally { + try { + conn.Value.ChangeDatabase(database); + _orm.Ado.MasterPool.Return(conn); + } catch { + _orm.Ado.MasterPool.Return(conn, true); } } - return sb.Length == 0 ? null : sb.ToString(); } ConcurrentDictionary dicSyced = new ConcurrentDictionary(); diff --git a/FreeSql/PostgreSQL/PostgreSQLCodeFirst.cs b/FreeSql/PostgreSQL/PostgreSQLCodeFirst.cs index b92cb8bc..712c6c20 100644 --- a/FreeSql/PostgreSQL/PostgreSQLCodeFirst.cs +++ b/FreeSql/PostgreSQL/PostgreSQLCodeFirst.cs @@ -101,8 +101,8 @@ namespace FreeSql.PostgreSQL { if (enumType == null && type.FullName.StartsWith("System.Nullable`1[") && type.GenericTypeArguments.Length == 1 && type.GenericTypeArguments.First().IsEnum) enumType = type.GenericTypeArguments.First(); if (enumType != null) { var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? - (NpgsqlDbType.Varchar, "varchar", $"varchar(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true) : - (NpgsqlDbType.Varchar, "varchar", $"varchar(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true); + (NpgsqlDbType.Bigint, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true) : + (NpgsqlDbType.Integer, "int4", $"int4{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true); if (_dicCsToDb.ContainsKey(type.FullName) == false) { lock (_dicCsToDbLock) { if (_dicCsToDb.ContainsKey(type.FullName) == false) @@ -118,23 +118,28 @@ namespace FreeSql.PostgreSQL { public string GetComparisonDDLStatements(params Type[] entityTypes) { var sb = new StringBuilder(); var seqcols = new List<(ColumnInfo, string[], bool)>(); //序列 + foreach (var entityType in entityTypes) { if (sb.Length > 0) sb.Append("\r\n"); var tb = _commonUtils.GetTableByEntity(entityType); + 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] }; - var isRenameTable = false; - var tbname = tb.DbName.Split(new[] { '.' }, 2); - if (tbname.Length == 1) tbname = new[] { "public", tbname[0] }; - if (_orm.Ado.ExecuteScalar(CommandType.Text, "select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = {0}.{1}".FormatPostgreSQL(tbname)) == null) { //表不存在 + if (string.Compare(tbname[0], "public", true) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, $"select 1 from pg_namespace where nspname='{tbname[0]}'") == null) //创建模式 + sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n"); - if (tboldname != null && _orm.Ado.ExecuteScalar(CommandType.Text, "select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = {0}.{1}".FormatPostgreSQL(tboldname)) != null) { //旧表存在 - //修改表名 - sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(";\r\n"); - isRenameTable = true; - - } else { + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format("select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = '{0}.{1}'", tbname)) == null) { //表不存在 + if (tboldname != null) { + if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format("select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where b.nspname || '.' || a.tablename = '{0}.{1}'", tboldname)) == null) + //旧表不存在 + tboldname = null; + } + if (tboldname == null) { //创建表 sb.Append("CREATE TABLE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ("); foreach (var tbcol in tb.Columns.Values) { @@ -151,19 +156,24 @@ namespace FreeSql.PostgreSQL { sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); continue; } - } + //如果新表,旧表在一个数据库和模式下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}")).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append(";\r\n"); + else { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } else + tboldname = null; //如果新表已经存在,不走改表名逻辑 + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 - var addcols = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - foreach (var tbcol in tb.Columns) addcols.Add(tbcol.Value.Attribute.Name, tbcol.Value); - var surplus = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - var dbcols = new List(); var sql = @"select a.attname, t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem = 0 then t.typname else t2.typname end, case when a.attnotnull then '0' else '1' end as is_nullable, -case when e.adsrc = 1 then '1' else '0' end as is_identity, +e.adsrc, a.attndims from pg_class c inner join pg_attribute a on a.attnum > 0 and a.attrelid = c.oid @@ -173,47 +183,96 @@ left join pg_description d on d.objoid = a.attrelid and d.objsubid = a.attnum left join pg_attrdef e on e.adrelid = a.attrelid and e.adnum = a.attnum inner join pg_namespace ns on ns.oid = c.relnamespace inner join pg_namespace ns2 on ns2.oid = t.typnamespace -where ns.nspname = {0} and c.relname = {1}".FormatPostgreSQL(isRenameTable ? tboldname : tbname); +where ns.nspname = {0} and c.relname = {1}".FormatPostgreSQL(tboldname ?? tbname); var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - foreach (var row in ds) { - string column = string.Concat(row[0]); - string sqlType = string.Concat(row[3]); - long max_length = long.Parse(string.Concat(row[2])); - bool is_nullable = string.Concat(row[4]) == "1"; - bool is_identity = string.Concat(row[5]).StartsWith(@"nextval('") && string.Concat(row[6]).EndsWith(@"_seq'::regclass)"); - var attndims = long.Parse(string.Concat(row[6])); - if (attndims > 0) sqlType += "[]"; + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => new { + column = string.Concat(a[0]), + sqlType = string.Concat(a[3], long.Parse(string.Concat(a[6])) > 0 ? "[]" : ""), + max_length = long.Parse(string.Concat(a[2])), + is_nullable = string.Concat(a[4]) == "1", + is_identity = string.Concat(a[5]).StartsWith(@"nextval('") && string.Concat(a[5]).EndsWith(@"'::regclass)"), + attndims = long.Parse(string.Concat(a[6])) + }, StringComparer.CurrentCultureIgnoreCase); - if (addcols.TryGetValue(column, out var trycol)) { - if (trycol.Attribute.DbType.ToLower().StartsWith(sqlType.ToLower()) == false || - (trycol.Attribute.DbType.IndexOf("NOT NULL") == -1) != is_nullable) { - sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(column)).Append(" TYPE ").Append(trycol.Attribute.DbType.ToUpper()).Append(";\r\n"); + if (istmpatler == false) { + foreach (var tbcol in tb.Columns.Values) { + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || + tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TYPE ").Append(tbcol.Attribute.DbType.ToUpper()).Append(";\r\n"); + break; + } + if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity)); + if (tbstructcol.column == tbcol.Attribute.OldName) { + //修改列名 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.OldName)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); + } + continue; } - if (trycol.Attribute.IsIdentity != is_identity) seqcols.Add((trycol, tbname, trycol.Attribute.IsIdentity)); - addcols.Remove(column); - } else { - if (trycol.Attribute.IsIdentity != is_identity) seqcols.Add((trycol, tbname, trycol.Attribute.IsIdentity)); - surplus.Add(column, true); //记录剩余字段 + //添加列 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.ToUpper()).Append(";\r\n"); + if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity)); } } - foreach (var addcol in addcols.Values) { - if (string.IsNullOrEmpty(addcol.Attribute.OldName) == false && surplus.ContainsKey(addcol.Attribute.OldName)) { //修改列名 - sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(addcol.Attribute.OldName)).Append(" TO ").Append(_commonUtils.QuoteSqlName(addcol.Attribute.Name)).Append(";\r\n"); - } else { //添加列 - sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD COLUMN ").Append(_commonUtils.QuoteSqlName(addcol.Attribute.Name)).Append(" ").Append(addcol.Attribute.DbType.ToUpper()).Append(";\r\n"); + if (istmpatler == false) { + sb.Append(sbalter); + continue; + } + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}"); + //创建临时表 + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.Columns.Values) { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType.ToUpper()).Append(","); + if (tbcol.Attribute.IsIdentity) seqcols.Add((tbcol, tbname, true)); + } + if (tb.Primarys.Any() == false) + sb.Remove(sb.Length - 1, 1); + else { + sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")"); + } + sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.Columns.Values) { + if (tbstruct.ContainsKey(tbcol.Attribute.Name) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.ContainsKey(tbcol.Attribute.OldName)) { //导入旧表存在的字段 + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); } } + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.Columns.Values) { + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { + var insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) { + var tbcoldbtype = tbcol.Attribute.DbType.Split(' ').First(); + insertvalue = $"cast({insertvalue} as {tbcoldbtype})"; + } + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { + insertvalue = $"ifnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")})"; + } + sb.Append(insertvalue).Append(", "); + } + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(";\r\n"); + sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName(tbname[1])).Append(";\r\n"); } - foreach(var seqcol in seqcols) { + foreach (var seqcol in seqcols) { var tbname = seqcol.Item2; var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name"); var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); - sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT null;"); - sb.Append("DROP SEQUENCE IF EXISTS ").Append(seqname).Append(";"); + sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT null;\r\n"); + sb.Append("DROP SEQUENCE IF EXISTS ").Append(seqname).Append(";\r\n"); if (seqcol.Item3) { - sb.Append("CREATE SEQUENCE ").Append(seqname).Append(" START WITH (select coalesce(max(").Append(colname2).Append("),1) from ").Append(tbname2).Append(");"); - sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT nextval('").Append(seqname).Append("'::regclass);"); + sb.Append("CREATE SEQUENCE ").Append(seqname).Append(";\r\n"); + sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT nextval('").Append(seqname).Append("'::regclass);\r\n"); + sb.Append("SELECT case when max(").Append(colname2).Append(") is null then 0 else setval('").Append(seqname).Append("', max(").Append(colname2).Append(")) end FROM ").Append(tbname2).Append(";\r\n"); } } return sb.Length == 0 ? null : sb.ToString(); diff --git a/FreeSql/PostgreSQL/PostgreSQLExpression.cs b/FreeSql/PostgreSQL/PostgreSQLExpression.cs index f303ffbb..64c7390c 100644 --- a/FreeSql/PostgreSQL/PostgreSQLExpression.cs +++ b/FreeSql/PostgreSQL/PostgreSQLExpression.cs @@ -195,9 +195,8 @@ namespace FreeSql.PostgreSQL { case "ToUInt32": case "ToUInt64": return $"cast({ExpressionLambdaToSql(exp.Arguments[0], _tables, _selectColumnMap, tbtype, isQuoteName)} as unsigned)"; } - throw new Exception($"MySqlExpression 未现实函数表达式 {exp} 解析"); } - throw new Exception($"MySqlExpression 未现实函数表达式 {exp} 解析"); + throw new Exception($"PostgreSQLExpression 未现实函数表达式 {exp} 解析"); } } } diff --git a/FreeSql/PostgreSQL/PostgreSQLProvider.cs b/FreeSql/PostgreSQL/PostgreSQLProvider.cs index ae6976bb..d98fbfd5 100644 --- a/FreeSql/PostgreSQL/PostgreSQLProvider.cs +++ b/FreeSql/PostgreSQL/PostgreSQLProvider.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.CommonProvider; -using FreeSql.MySql.Curd; +using FreeSql.PostgreSQL.Curd; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; @@ -11,15 +11,15 @@ namespace FreeSql.PostgreSQL { class PostgreSQLProvider : IFreeSql { - public ISelect Select() where T1 : class => new MySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public ISelect Select(object dywhere) where T1 : class => new MySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IInsert Insert() where T1 : class => new MySqlInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public ISelect Select() where T1 : class => new PostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public ISelect Select(object dywhere) where T1 : class => new PostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IInsert Insert() where T1 : class => new PostgreSQLInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); - public IUpdate Update() where T1 : class => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IUpdate Update(object dywhere) where T1 : class => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); - public IDelete Delete() where T1 : class => new MySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); - public IDelete Delete(object dywhere) where T1 : class => new MySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IUpdate Update() where T1 : class => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IUpdate Update(object dywhere) where T1 : class => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public IDelete Delete() where T1 : class => new PostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); + public IDelete Delete(object dywhere) where T1 : class => new PostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public IAdo Ado { get; } public ICache Cache { get; } @@ -29,7 +29,7 @@ namespace FreeSql.PostgreSQL { CacheStrategy = cacheStrategy; if (log == null) log = new LoggerFactory(new[] { new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider() }).CreateLogger("FreeSql.PostgreSQL"); - this.InternalCommonUtils = new MySqlUtils(this); + this.InternalCommonUtils = new PostgreSQLUtils(this); this.InternalCommonExpression = new PostgreSQLExpression(this.InternalCommonUtils); this.Cache = new CacheProvider(cache, log); diff --git a/FreeSql/PostgreSQL/PostgreSQLUtils.cs b/FreeSql/PostgreSQL/PostgreSQLUtils.cs index 39ea1bd0..7a8d09f4 100644 --- a/FreeSql/PostgreSQL/PostgreSQLUtils.cs +++ b/FreeSql/PostgreSQL/PostgreSQLUtils.cs @@ -8,10 +8,10 @@ using System.Linq; namespace FreeSql.PostgreSQL { - class MySqlUtils : CommonUtils { + class PostgreSQLUtils : CommonUtils { IFreeSql _orm; - public MySqlUtils(IFreeSql mysql) { - _orm = mysql; + public PostgreSQLUtils(IFreeSql orm) { + _orm = orm; } internal override DbParameter AppendParamter(List _params, string parameterName, object value) { @@ -24,12 +24,12 @@ namespace FreeSql.PostgreSQL { ParameterName = parameterName, Value = value }; - if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { - ret.DataTypeName = ""; - } else { + //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { + // ret.DataTypeName = ""; + //} else { var tp = _orm.CodeFirst.GetDbInfo(type)?.type; if (tp != null) ret.NpgsqlDbType = (NpgsqlDbType)tp.Value; - } + //} } _params?.Add(ret); return ret; @@ -41,16 +41,16 @@ namespace FreeSql.PostgreSQL { ParameterName = name, Value = value ?? DBNull.Value }; - if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { - ret.DataTypeName = ""; - } else { + //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { + // ret.DataTypeName = ""; + //} else { var tp = _orm.CodeFirst.GetDbInfo(type)?.type; if (tp != null) ret.NpgsqlDbType = (NpgsqlDbType)tp.Value; - } + //} return ret; }); - internal override string FormatSql(string sql, params object[] args) => sql?.FormatMySql(args); + internal override string FormatSql(string sql, params object[] args) => sql?.FormatPostgreSQL(args); internal override string QuoteSqlName(string name) => $"\"{name.Trim('"').Replace(".", "\".\"")}\""; internal override string QuoteParamterName(string name) => $"@{name}"; internal override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; diff --git a/FreeSql/SqlServer/SqlServerCodeFirst.cs b/FreeSql/SqlServer/SqlServerCodeFirst.cs index 8709537a..27fce117 100644 --- a/FreeSql/SqlServer/SqlServerCodeFirst.cs +++ b/FreeSql/SqlServer/SqlServerCodeFirst.cs @@ -72,43 +72,76 @@ namespace FreeSql.SqlServer { public string GetComparisonDDLStatements() => this.GetComparisonDDLStatements(typeof(TEntity)); public string GetComparisonDDLStatements(params Type[] entityTypes) { - var sb = new StringBuilder(); - foreach (var entityType in entityTypes) { - if (sb.Length > 0) sb.Append("\r\n"); - var tb = _commonUtils.GetTableByEntity(entityType); - var tboldname = tb.DbOldName?.Split(new[] { '.' }, 2); //旧表名 - if (tboldname?.Length == 1) tboldname = new[] { "dbo", tboldname[0] }; - - var isRenameTable = false; - var tbname = tb.DbName.Split(new[] { '.' }, 2); - if (tbname.Length == 1) tbname = new[] { "dbo", tbname[0] }; - if (_orm.Ado.ExecuteScalar(CommandType.Text, string.Format("select 1 from dbo.sysobjects where id = object_id(N'[{0}].[{1}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1", tbname)) == null) { //表不存在 - - if (tboldname != null && _orm.Ado.ExecuteScalar(CommandType.Text, string.Format("select 1 from dbo.sysobjects where id = object_id(N'[{0}].[{1}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1", tboldname)) != null) { //旧表存在 - //修改表名 - sb.Append(_commonUtils.FormatSql("EXEC sp_rename {0}, {1};\r\n", _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"), _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"))); - isRenameTable = true; - - } else { - //创建表 - sb.Append("CREATE TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ("); - foreach (var tbcol in tb.Columns.Values) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); - if (tbcol.Attribute.IsPrimary) sb.Append(" primary key"); - sb.Append(","); - } - sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); - continue; + var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); + var database = conn.Value.Database; + Func ExecuteScalar = (db, sql) => { + if (string.Compare(database, db) != 0) try { conn.Value.ChangeDatabase(db); } catch { } + try { + using (var cmd = conn.Value.CreateCommand()) { + cmd.CommandText = sql; + cmd.CommandType = CommandType.Text; + return cmd.ExecuteScalar(); } + } finally { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(database); } - //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 - var addcols = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - foreach (var tbcol in tb.Columns) addcols.Add(tbcol.Value.Attribute.Name, tbcol.Value); - var surplus = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - var dbcols = new List(); - var sql = string.Format(@"select + }; + var sb = new StringBuilder(); + try { + foreach (var entityType in entityTypes) { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(entityType); + 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] }; + + 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.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]}];"); + if (string.Compare(tbname[1], "dbo", true) != 0 && ExecuteScalar(tbname[0], $"select 1 from sys.schemas where name='{tbname[1]}'") == null) //创建模式 + ExecuteScalar(tbname[0], $"create schema [{tbname[1]}] authorization [dbo]"); + + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (ExecuteScalar(tbname[0], $"select 1 from dbo.sysobjects where id = object_id(N'[{tbname[1]}].[{tbname[2]}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1") == null) { //表不存在 + if (tboldname != null) { + if (string.Compare(tboldname[0], tbname[0], true) != 0 && ExecuteScalar(database, $"select 1 from sys.databases where name='{tboldname[0]}'") == null || + string.Compare(tboldname[1], tbname[1], true) != 0 && ExecuteScalar(tboldname[0], $"select 1 from sys.schemas where name='{tboldname[1]}'") == null || + ExecuteScalar(tboldname[0], $"select 1 from dbo.sysobjects where id = object_id(N'[{tboldname[1]}].[{tboldname[2]}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1") == null) + //数据库或模式或表不存在 + tboldname = null; + } + if (tboldname == null) { + //创建新表 + sb.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(";\r\nCREATE TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}.{tbname[2]}")).Append(" ("); + foreach (var tbcol in tb.Columns.Values) { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); + sb.Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); + if (tbcol.Attribute.IsPrimary) sb.Append(" primary key"); + sb.Append(","); + } + sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); + continue; + } + //如果新表,旧表在一个数据库和模式下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0 && + string.Compare(tbname[1], tboldname[1], true) == 0) + sbalter.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(_commonUtils.FormatSql(";\r\nEXEC sp_rename {0}, {1};\r\n", _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"), _commonUtils.QuoteSqlName(tbname[2]))); + else { + //如果新表,旧表不在一起,创建新表,导入数据,删除旧表 + istmpatler = true; + } + } else + tboldname = null; //如果新表已经存在,不走改表名逻辑 + + //对比字段,只可以修改类型、增加字段、有限的修改字段名;保证安全不删除字段 + var sql = string.Format(@" +use [{0}]; +select a.name 'Column' ,b.name + case when b.name in ('Char', 'VarChar', 'NChar', 'NVarChar', 'Binary', 'VarBinary') then '(' + @@ -124,99 +157,110 @@ inner join sys.types b on b.user_type_id = a.user_type_id left join sys.extended_properties AS c ON c.major_id = a.object_id AND c.minor_id = a.column_id left join sys.tables d on d.object_id = a.object_id left join sys.schemas e on e.schema_id = d.schema_id -where a.object_id in (object_id(N'[{0}].[{1}]'))", isRenameTable ? tboldname : tbname); - var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); - var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => new { - column = string.Concat(a[0]), - sqlType = string.Concat(a[1]), - is_nullable = string.Concat(a[2]) == "1", - is_identity = string.Concat(a[3]) == "1" - }, StringComparer.CurrentCultureIgnoreCase); - var sbalter = new StringBuilder(); - var istmpatler = false; - foreach (var tbcol in tb.Columns.Values) { - if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || - string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { - if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || - tbcol.Attribute.IsNullable != tbstructcol.is_nullable || - tbcol.Attribute.IsIdentity != tbstructcol.is_identity) { - istmpatler = true; - break; - } - if (tbstructcol.column == tbcol.Attribute.OldName) { - //修改列名 - sbalter.Append(_commonUtils.FormatSql("EXEC sp_rename {0}, {1}, 'COLUMN';\r\n", $"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.OldName}", tbcol.Attribute.Name)); +where a.object_id in (object_id(N'[{1}].[{2}]')); +use " + database, tboldname ?? tbname); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => new { + column = string.Concat(a[0]), + sqlType = string.Concat(a[1]), + is_nullable = string.Concat(a[2]) == "1", + is_identity = string.Concat(a[3]) == "1" + }, StringComparer.CurrentCultureIgnoreCase); + + if (istmpatler == false) { + foreach (var tbcol in tb.Columns.Values) { + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false || + tbcol.Attribute.IsNullable != tbstructcol.is_nullable || + tbcol.Attribute.IsIdentity != tbstructcol.is_identity) { + istmpatler = true; + break; + } + if (tbstructcol.column == tbcol.Attribute.OldName) { + //修改列名 + sbalter.Append(_commonUtils.FormatSql("EXEC sp_rename {0}, {1}, 'COLUMN';\r\n", $"{tbname[0]}.{tbname[1]}.{tbname[2]}.{tbcol.Attribute.OldName}", tbcol.Attribute.Name)); + } + continue; + } + //添加列 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" identity(1,1)"); + var addcoldbdefault = tb.Properties[tbcol.CsName].GetValue(Activator.CreateInstance(tb.Type)); + if (tbcol.Attribute.IsNullable == false) addcoldbdefault = tbcol.Attribute.DbDefautValue; + if (addcoldbdefault != null) sbalter.Append(_commonUtils.FormatSql(" default({0})", addcoldbdefault)); + sbalter.Append(";\r\n"); } + } + if (istmpatler == false) { + sb.Append(sbalter); continue; } - //添加列 - sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" identity(1,1)"); - var addcoldbdefault = tb.Properties[tbcol.CsName].GetValue(Activator.CreateInstance(tb.Type)); - if (tbcol.Attribute.IsNullable == false) addcoldbdefault = tbcol.Attribute.DbDefautValue; - if (addcoldbdefault != null) sbalter.Append(_commonUtils.FormatSql(" default({0})", addcoldbdefault)); - sbalter.Append(";\r\n"); - } - if (istmpatler == false) { - sb.Append(sbalter); - continue; - } - //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 - bool idents = false; - var tablename = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); - var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.TmpFreeSqlTmp_{tbname[1]}"); - sb.Append("BEGIN TRANSACTION\r\n") - .Append("SET QUOTED_IDENTIFIER ON\r\n") - .Append("SET ARITHABORT ON\r\n") - .Append("SET NUMERIC_ROUNDABORT OFF\r\n") - .Append("SET CONCAT_NULL_YIELDS_NULL ON\r\n") - .Append("SET ANSI_NULLS ON\r\n") - .Append("SET ANSI_PADDING ON\r\n") - .Append("SET ANSI_WARNINGS ON\r\n") - .Append("COMMIT\r\n"); - sb.Append("BEGIN TRANSACTION;\r\n"); - //创建临时表 - sb.Append("CREATE TABLE ").Append(tmptablename).Append(" ("); - foreach (var tbcol in tb.Columns.Values) { - sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); - sb.Append(tbcol.Attribute.DbType); - if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); - if (tbcol.Attribute.IsPrimary) sb.Append(" primary key"); - sb.Append(","); - idents = idents || tbcol.Attribute.IsIdentity; - } - sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); - sb.Append("ALTER TABLE ").Append(tmptablename).Append(" SET (LOCK_ESCALATION = TABLE);\r\n"); - if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" ON;\r\n"); - sb.Append("IF EXISTS(SELECT 1 FROM ").Append(tablename).Append(")\r\n"); - sb.Append("\tEXEC('INSERT INTO ").Append(tmptablename).Append(" ("); - foreach (var tbcol in tb.Columns.Values) { - if (tbstruct.ContainsKey(tbcol.Attribute.Name) || tbstruct.ContainsKey(tbcol.Attribute.OldName)) { //导入旧表存在的字段 - sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + bool idents = false; + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}.{tboldname[2]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.FreeSqlTmp_{tbname[2]}"); + sb.Append("BEGIN TRANSACTION\r\n") + .Append("SET QUOTED_IDENTIFIER ON\r\n") + .Append("SET ARITHABORT ON\r\n") + .Append("SET NUMERIC_ROUNDABORT OFF\r\n") + .Append("SET CONCAT_NULL_YIELDS_NULL ON\r\n") + .Append("SET ANSI_NULLS ON\r\n") + .Append("SET ANSI_PADDING ON\r\n") + .Append("SET ANSI_WARNINGS ON\r\n") + .Append("COMMIT\r\n"); + sb.Append("BEGIN TRANSACTION;\r\n"); + //创建临时表 + sb.Append("CREATE TABLE ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.Columns.Values) { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" "); + sb.Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); + if (tbcol.Attribute.IsPrimary) sb.Append(" primary key"); + sb.Append(","); + idents = idents || tbcol.Attribute.IsIdentity; } - } - sb.Remove(sb.Length - 2, 2).Append(")\r\n\t\tSELECT "); - foreach (var tbcol in tb.Columns.Values) { - if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || - string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { - var insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); - if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) { - var tbcoldbtype = tbcol.Attribute.DbType.Split(' ').First(); - insertvalue = $"cast({insertvalue} as {tbcoldbtype})"; + sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); + sb.Append("ALTER TABLE ").Append(tmptablename).Append(" SET (LOCK_ESCALATION = TABLE);\r\n"); + if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" ON;\r\n"); + sb.Append("IF EXISTS(SELECT 1 FROM ").Append(tablename).Append(")\r\n"); + sb.Append("\tEXEC('INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.Columns.Values) { + if (tbstruct.ContainsKey(tbcol.Attribute.Name) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.ContainsKey(tbcol.Attribute.OldName)) { //导入旧表存在的字段 + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); } - if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { - insertvalue = $"isnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")})"; - } - sb.Append(insertvalue).Append(", "); } + sb.Remove(sb.Length - 2, 2).Append(")\r\n\t\tSELECT "); + foreach (var tbcol in tb.Columns.Values) { + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) { + var insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) { + var tbcoldbtype = tbcol.Attribute.DbType.Split(' ').First(); + insertvalue = $"cast({insertvalue} as {tbcoldbtype})"; + } + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { + insertvalue = $"isnull({insertvalue},{_commonUtils.FormatSql("{0}", tbcol.Attribute.DbDefautValue).Replace("'", "''")})"; + } + sb.Append(insertvalue).Append(", "); + } + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(" WITH (HOLDLOCK TABLOCKX)');\r\n"); + if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" OFF;\r\n"); + sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); + sb.Append("EXECUTE sp_rename N'").Append(tmptablename).Append("', N'").Append(tbname[2]).Append("', 'OBJECT' ;\r\n"); + sb.Append("COMMIT;\r\n"); + } + return sb.Length == 0 ? null : sb.ToString(); + } finally { + try { + conn.Value.ChangeDatabase(database); + _orm.Ado.MasterPool.Return(conn); + } catch { + _orm.Ado.MasterPool.Return(conn, true); } - sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append(" WITH (HOLDLOCK TABLOCKX)');\r\n"); - if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" OFF;\r\n"); - sb.Append("DROP TABLE ").Append(tablename).Append(";\r\n"); - sb.Append("EXECUTE sp_rename N'").Append(tmptablename).Append("', N'").Append(tbname[1]).Append("', 'OBJECT' ;\r\n"); - sb.Append("COMMIT;\r\n"); } - return sb.Length == 0 ? null : sb.ToString(); } ConcurrentDictionary dicSyced = new ConcurrentDictionary(); diff --git a/readme.md b/readme.md index 69775e39..b996a1d9 100644 --- a/readme.md +++ b/readme.md @@ -119,10 +119,11 @@ sql = select.LeftJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name //SELECT a.`Id` as1, a.`Clicks` as2, a.`TestTypeInfoGuid` as3, a.`Title` as4, a.`CreateTime` as5 FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name = ?bname ``` -# 表达式函数 +## 表达式函数 | 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 | | - | - | - | - | - | -| (a ?? b) | ifnull(a, b) | isnull(a, b) | coalesce(a, b) | 当a为null时,取b值 | +| a ? b : c | case when a then b else c end | case when a then b else c end | - | a成立时取b值,否则取c值 | +| a ?? b | ifnull(a, b) | isnull(a, b) | coalesce(a, b) | 当a为null时,取b值 | | 数字 + 数字 | a + b | a + b | a + b | 数字相加 | | 数字 + 字符串 | concat(a, b) | cast(a as varchar) + cast(b as varchar) | case(a as varchar) \|\| b | 字符串相加,a或b任意一个为字符串时 | | a - b | a - b | a - b | a - b | 减 @@ -136,113 +137,133 @@ sql = select.LeftJoin("TestTypeInfo b on b.Guid = a.TestTypeInfoGuid and b.Name | 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 | | - | - | - | - | - | | string.Empty | '' | '' | '' | 空字符串表示 | -| a.CompareTo(b) | a - b | - | - | 比较a和b大小 | -| a.Contains('b') | a like '%b%' | - | - | a是否包含b | -| a.EndsWith('b') | a like '%b' | - | - | a尾部是否包含b | -| a.IndexOf(b) | locate(a, b) - 1 | - | - | 查找a中出现b的位置 | -| a.Length | char_length(a) | - | - | 返回a的字符串长度 | +| a.CompareTo(b) | strcmp(a, b) | - | - | 比较a和b大小 | +| a.Contains('b') | a like '%b%' | a like '%b%' | - | a是否包含b | +| a.EndsWith('b') | a like '%b' | a like '%b' | - | a尾部是否包含b | +| a.IndexOf(b) | locate(a, b) - 1 | locate(a, b) - 1 | - | 查找a中出现b的位置 | +| a.Length | char_length(a) | len(a) | - | 返回a的字符串长度 | | a.PadLeft(b, c) | lpad(a, b, c) | - | - | 在a的左侧充字符c,直到字符串长度大于b | | a.PadRight(b, c) | rpad(a, b, c) | - | - | 在a的右侧充字符c,直到字符串长度大于b | -| a.Replace(b, c) | replace(a, b, c) | - | - | 将a中字符串b,替换成c | -| a.StartsWith('b') | a like 'b%' | - | - | a头部是否包含b | -| a.Substring(b, c) | substr(a, b, c) | - | - | 截取a中位置b到c的内容 | -| a.ToLower | lower(a) | - | - | 转小写 | -| a.ToUpper | upper(a) | - | - | 转大写 | -| a.Trim | trim(a) | - | - | 移除两边字符 | -| a.TrimEnd | rtrim(a) | - | - | 移除左侧指定字符 | -| a.TrimStart | ltrim(a) | - | - | 移除右侧指定字符 | +| a.Replace(b, c) | replace(a, b, c) | replace(a, b, c) | - | 将a中字符串b,替换成c | +| a.StartsWith('b') | a like 'b%' | a like 'b%' | - | a头部是否包含b | +| a.Substring(b, c) | substr(a, b, c) | substring(a, b, c) | - | 截取a中位置b到c的内容 | +| a.ToLower | lower(a) | lower(a) | - | 转小写 | +| a.ToUpper | upper(a) | upper(a) | - | 转大写 | +| a.Trim | trim(a) | trim(a) | - | 移除两边字符 | +| a.TrimEnd | rtrim(a) | rtrim(a) | - | 移除左侧指定字符 | +| a.TrimStart | ltrim(a) | ltrim(a) | - | 移除右侧指定字符 | ### 日期对象 | 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 | | - | - | - | - | - | -| DateTime.Now | now() | - | - | 取本地时间 | -| DateTime.UtcNow | utc_timestamp() | - | - | 取UTC时间 | -| DateTime.Today | curdate | - | - | 取本地时间,日期部分 | -| DateTime.MaxValue | cast('9999/12/31 23:59:59' as datetime) | - | - | 最大时间 | -| DateTime.MinValue | cast('0001/1/1 0:00:00' as datetime) | - | - | 最小时间 | -| DateTime.Compare(a, b) | a - b | - | - | 比较a和b的大小 | -| DateTime.DaysInMonth(a, b) | dayofmonth(last_day(concat(a, '-', b, '-1'))) | - | - | 取指定年月份的总天数 | -| DateTime.Equals(a, b) | a = b | - | - | 比较a和b相等 | -| DateTime.IsLeapYear(a) | a%4=0 and a%100<>0 or a%400=0 | - | - | 判断闰年 | -| DateTime.Parse(a) | cast(a as datetime) | - | - | 转换日期类型 | -| a.Add(b) | date_add(a, interval b microsecond) | - | - | 增加TimeSpan值 | -| a.AddDays(b) | date_add(a, interval b day) | - | - | 增加天数 | -| a.AddHours(b) | date_add(a, interval b hour) | - | - | 增加小时 | -| a.AddMilliseconds(b) | date_add(a, interval b*1000 microsecond) | - | - | 增加毫秒 | -| a.AddMinutes(b) | date_add(a, interval b minute) | - | - | 增加分钟 | -| a.AddMonths(b) | date_add(a, interval b month) | - | - | 增加月 | -| a.AddSeconds(b) | date_add(a, interval b second) | - | - | 增加秒 | -| a.AddTicks(b) | date_add(a, interval b/10 microsecond) | - | - | 增加刻度,微秒的1/10 | -| a.AddYears(b) | date_add(a, interval b year) | - | - | 增加年 | -| a.Date | cast(date_format(a, '%Y-%m-%d') as datetime) | - | - | 获取a的日期部分 | -| a.Day | dayofmonth(a) | - | - | 获取a在月的第几天 | -| a.DayOfWeek | dayofweek(a) | - | - | 获取a在周的第几天 | -| a.DayOfYear | dayofyear(a) | - | - | 获取a在年的第几天 | -| a.Hour | hour(a) | - | - | 小时 | -| a.Millisecond | floor(microsecond(a) / 1000) | - | - | 毫秒 | -| a.Minute | minute(a) | - | - | 分钟 | -| a.Month | month(a) | - | - | 月 | -| a.Second | second(a) | - | - | 秒 | -| a.Subtract(b) | (time_to_sec(a) - time_to_sec(b)) * 1000000 + microsecond(a) - microsecond(b) | - | - | 将a的值和b相减 | -| a.Ticks | time_to_sec(a) * 10000000 + microsecond(a) * 10 + 62135596800000000 | - | - | 刻度总数 | -| a.TimeOfDay | time_to_sec(date_format(a, '1970-1-1 %H:%i:%s.%f')) * 1000000 + microsecond(a) + 6213559680000000 | - | - | 获取a的时间部分 | -| a.Year | year(a) | - | - | 年 | -| a.Equals(b) | a = b | - | - | 比较a和b相等 | -| a.CompareTo(b) | a - b | - | - | 比较a和b大小 | -| a.ToString() | date_format(a, '%Y-%m-%d %H:%i:%s.%f') | - | - | 转换字符串 | +| DateTime.Now | now() | getdate() | - | 取本地时间 | +| DateTime.UtcNow | utc_timestamp() | getutcdate() | - | 取UTC时间 | +| DateTime.Today | curdate | convert(char(10),getdate(),120) | - | 取本地时间,日期部分 | +| DateTime.MaxValue | cast('9999/12/31 23:59:59' as datetime) | '1753/1/1 0:00:00' | - | 最大时间 | +| DateTime.MinValue | cast('0001/1/1 0:00:00' as datetime) | '9999/12/31 23:59:59' | - | 最小时间 | +| DateTime.Compare(a, b) | a - b | a - b | - | 比较a和b的大小 | +| DateTime.DaysInMonth(a, b) | dayofmonth(last_day(concat(a, '-', b, '-1'))) | datepart(day, dateadd(day, -1, dateadd(month, 1, cast(a as varchar) + '-' + cast(b as varchar) + '-1'))) | - | 取指定年月份的总天数 | +| DateTime.Equals(a, b) | a = b | a = b | - | 比较a和b相等 | +| DateTime.IsLeapYear(a) | a%4=0 and a%100<>0 or a%400=0 | a%4=0 and a%100<>0 or a%400=0 | - | 判断闰年 | +| DateTime.Parse(a) | cast(a as datetime) | cast(a as datetime) | - | 转换日期类型 | +| a.Add(b) | date_add(a, interval b microsecond) | dateadd(millisecond, b / 1000, a) | - | 增加TimeSpan值 | +| a.AddDays(b) | date_add(a, interval b day) | dateadd(day, b, a) | - | 增加天数 | +| a.AddHours(b) | date_add(a, interval b hour) | dateadd(hour, b, a) | - | 增加小时 | +| a.AddMilliseconds(b) | date_add(a, interval b*1000 microsecond) | dateadd(millisecond, b, a) | - | 增加毫秒 | +| a.AddMinutes(b) | date_add(a, interval b minute) | dateadd(minute, b, a) | - | 增加分钟 | +| a.AddMonths(b) | date_add(a, interval b month) | dateadd(month, b, a) | - | 增加月 | +| a.AddSeconds(b) | date_add(a, interval b second) | dateadd(second, b, a) | - | 增加秒 | +| a.AddTicks(b) | date_add(a, interval b/10 microsecond) | dateadd(millisecond, b / 10000, a) | - | 增加刻度,微秒的1/10 | +| a.AddYears(b) | date_add(a, interval b year) | dateadd(year, b, a) | - | 增加年 | +| a.Date | cast(date_format(a, '%Y-%m-%d') as datetime) | convert(char(10),a,120) | - | 获取a的日期部分 | +| a.Day | dayofmonth(a) | datepart(day, a) | - | 获取a在月的第几天 | +| a.DayOfWeek | dayofweek(a) | datepart(weekday, a) - 1 | - | 获取a在周的第几天 | +| a.DayOfYear | dayofyear(a) | datepart(dayofyear, a) | - | 获取a在年的第几天 | +| a.Hour | hour(a) | datepart(hour, a) | - | 小时 | +| a.Millisecond | floor(microsecond(a) / 1000) | datepart(millisecond, a) | - | 毫秒 | +| a.Minute | minute(a) | datepart(minute, a) | - | 分钟 | +| a.Month | month(a) | datepart(month, a) | - | 月 | +| a.Second | second(a) | datepart(second, a) | - | 秒 | +| a.Subtract(b) | timestampdiff(microsecond, b, a) | datediff(millisecond, b, a) * 1000 | - | 将a的值和b相减 | +| a.Ticks | timestampdiff(microsecond, '0001-1-1', a) * 10 | datediff(millisecond, '1970-1-1', a) * 10000 + 621355968000000000 | - | 刻度总数 | +| a.TimeOfDay | timestampdiff(microsecond, date_format(a, '%Y-%m-%d'), a) | '1970-1-1 ' + convert(varchar, a, 14) | - | 获取a的时间部分 | +| a.Year | year(a) | datepart(year, a) | - | 年 | +| a.Equals(b) | a = b | a = b | - | 比较a和b相等 | +| a.CompareTo(b) | a - b | a - b | - | 比较a和b大小 | +| a.ToString() | date_format(a, '%Y-%m-%d %H:%i:%s.%f') | convert(varchar, a, 121) | - | 转换字符串 | ### 时间对象 -| 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 | +| 表达式 | MySql(微秒) | SqlServer(秒) | PostgreSQL | 功能说明 | | - | - | - | - | - | -| TimeSpan.Zero | 0 | - | - | 0微秒 | -| TimeSpan.MaxValue | 922337203685477580 | - | - | 最大微秒时间 | -| TimeSpan.MinValue | -922337203685477580 | - | - | 最小微秒时间 | -| TimeSpan.Compare(a, b) | a - b | - | - | 比较a和b的大小 | -| TimeSpan.Equals(a, b) | a = b | - | - | 比较a和b相等 | -| TimeSpan.FromDays(a) | a * 1000000 * 60 * 60 * 24 | - | - | a天的微秒值 | -| TimeSpan.FromHours(a) | a * 1000000 * 60 * 60 | - | - | a小时的微秒值 | -| TimeSpan.FromMilliseconds(a) | a * 1000 | - | - | a毫秒的微秒值 | -| TimeSpan.FromMinutes(a) | a * 1000000 * 60 | - | - | a分钟的微秒值 | -| TimeSpan.FromSeconds(a) | a * 1000000 | - | - | a秒钟的微秒值 | -| TimeSpan.FromTicks(a) | a / 10 | - | - | a刻度的毫秒值 | -| a.Add(b) | a + b | - | - | 增加值 | -| a.Subtract(b) | a - b | - | - | 将a的值和b相减 | -| a.CompareTo(b) | a - b | - | - | 比较a和b大小 | -| a.Days | a div (1000000 * 60 * 60 * 24) | - | - | 天数部分 | -| a.Hours | a div (1000000 * 60 * 60) mod 24 | - | - | 小时部分 | -| a.Milliseconds | a div 1000 mod 1000 | - | - | 毫秒部分 | -| a.Seconds | a div 1000000 mod 60 | - | - | 秒数部分 | -| a.Ticks | a * 10 | - | - | 刻度总数 | -| a.TotalDays | a / (1000000 * 60 * 60 * 24) | - | - | 总天数(含小数) | -| a.TotalHours | a / (1000000 * 60 * 60) | - | - | 总小时(含小数) | -| a.TotalMilliseconds | a / 1000 | - | - | 总毫秒(含小数) | -| a.TotalMinutes | a / (1000000 * 60) | - | - | 总分钟(含小数) | -| a.TotalSeconds | a / 1000000 | - | - | 总秒数(含小数) | -| a.Equals(b) | a = b | - | - | 比较a和b相等 | -| a.ToString() | | - | - | 转换字符串 | +| TimeSpan.Zero | 0 | 0 | - | 0微秒 | +| TimeSpan.MaxValue | 922337203685477580 | 922337203685477580 | - | 最大微秒时间 | +| TimeSpan.MinValue | -922337203685477580 | -922337203685477580 | - | 最小微秒时间 | +| TimeSpan.Compare(a, b) | a - b | a - b | - | 比较a和b的大小 | +| TimeSpan.Equals(a, b) | a = b | a = b | - | 比较a和b相等 | +| TimeSpan.FromDays(a) | a * 1000000 * 60 * 60 * 24 | a * 1000000 * 60 * 60 * 24 | - | a天的微秒值 | +| TimeSpan.FromHours(a) | a * 1000000 * 60 * 60 | a * 1000000 * 60 * 60 | - | a小时的微秒值 | +| TimeSpan.FromMilliseconds(a) | a * 1000 | a * 1000 | - | a毫秒的微秒值 | +| TimeSpan.FromMinutes(a) | a * 1000000 * 60 | a * 1000000 * 60 | - | a分钟的微秒值 | +| TimeSpan.FromSeconds(a) | a * 1000000 | a * 1000000 | - | a秒钟的微秒值 | +| TimeSpan.FromTicks(a) | a / 10 | a / 10 | - | a刻度的毫秒值 | +| a.Add(b) | a + b | a + b | - | 增加值 | +| a.Subtract(b) | a - b | a - b | - | 将a的值和b相减 | +| a.CompareTo(b) | a - b | a - b | - | 比较a和b大小 | +| a.Days | a div (1000000 * 60 * 60 * 24) | a div (1000000 * 60 * 60 * 24) | - | 天数部分 | +| a.Hours | a div (1000000 * 60 * 60) mod 24 | a div (1000000 * 60 * 60) mod 24 | - | 小时部分 | +| a.Milliseconds | a div 1000 mod 1000 | a div 1000 mod 1000 | - | 毫秒部分 | +| a.Seconds | a div 1000000 mod 60 | a div 1000000 mod 60 | - | 秒数部分 | +| a.Ticks | a * 10 | a * 10 | - | 刻度总数 | +| a.TotalDays | a / (1000000 * 60 * 60 * 24) | a / (1000000 * 60 * 60 * 24) | - | 总天数(含小数) | +| a.TotalHours | a / (1000000 * 60 * 60) | a / (1000000 * 60 * 60) | - | 总小时(含小数) | +| a.TotalMilliseconds | a / 1000 | a / 1000 | - | 总毫秒(含小数) | +| a.TotalMinutes | a / (1000000 * 60) | a / (1000000 * 60) | - | 总分钟(含小数) | +| a.TotalSeconds | a / 1000000 | a / 1000000 | - | 总秒数(含小数) | +| a.Equals(b) | a = b | a = b | - | 比较a和b相等 | +| a.ToString() | cast(a as varchar) | cast(a as varchar) | - | 转换字符串 | ### 数学函数 | 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 | | - | - | - | - | - | -| Math.Abs(a) | abs(a) | - | - | - | -| Math.Acos(a) | acos(a) | - | - | - | -| Math.Asin(a) | asin(a) | - | - | - | -| Math.Atan(a) | atan(a) | - | - | - | -| Math.Atan2(a, b) | atan2(a, b) | - | - | - | -| Math.Ceiling(a) | ceiling(a) | - | - | - | -| Math.Cos(a) | cos(a) | - | - | - | -| Math.Exp(a) | exp(a) | - | - | - | -| Math.Floor(a) | floor(a) | - | - | - | -| Math.Log(a) | log(a) | - | - | - | -| Math.Log10(a) | log10(a) | - | - | - | -| Math.PI(a) | 3.1415926535897931 | - | - | - | -| Math.Pow(a, b) | pow(a, b) | - | - | - | -| Math.Round(a, b) | round(a, b) | - | - | - | -| Math.Sign(a) | sign(a) | - | - | - | -| Math.Sin(a) | sin(a) | - | - | - | -| Math.Sqrt(a) | sqrt(a) | - | - | - | -| Math.Tan(a) | tan(a) | - | - | - | -| Math.Truncate(a) | truncate(a, 0) | - | - | - | +| Math.Abs(a) | abs(a) | abs(a) | - | - | +| Math.Acos(a) | acos(a) | acos(a) | - | - | +| Math.Asin(a) | asin(a) | asin(a) | - | - | +| Math.Atan(a) | atan(a) | atan(a) | - | - | +| Math.Atan2(a, b) | atan2(a, b) | atan2(a, b) | - | - | +| Math.Ceiling(a) | ceiling(a) | ceiling(a) | - | - | +| Math.Cos(a) | cos(a) | cos(a) | - | - | +| Math.Exp(a) | exp(a) | exp(a) | - | - | +| Math.Floor(a) | floor(a) | floor(a) | - | - | +| Math.Log(a) | log(a) | log(a) | - | - | +| Math.Log10(a) | log10(a) | log10(a) | - | - | +| Math.PI(a) | 3.1415926535897931 | 3.1415926535897931 | - | - | +| Math.Pow(a, b) | pow(a, b) | power(a, b) | - | - | +| Math.Round(a, b) | round(a, b) | round(a, b) | - | - | +| Math.Sign(a) | sign(a) | sign(a) | - | - | +| Math.Sin(a) | sin(a) | sin(a) | - | - | +| Math.Sqrt(a) | sqrt(a) | sqrt(a) | - | - | +| Math.Tan(a) | tan(a) | tan(a) | - | - | +| Math.Truncate(a) | truncate(a, 0) | floor(a) | - | - | + +### 类型转换 +| 表达式 | MySql | SqlServer | PostgreSQL | 功能说明 | +| - | - | - | - | - | +| Convert.ToBoolean(a) | (a not in ('0','false)) | - | - | - | +| Convert.ToByte | cast(a as unsigned) | - | - | - | +| Convert.ToChar | substr(cast(a as char),1,1) | - | - | - | +| Convert.ToDateTime | cast(a as datetime) | - | - | - | +| Convert.ToDecimal | cast(a as decimal(36,18)) | - | - | - | +| Convert.ToDouble | cast(a as decimal(32,16)) | - | - | - | +| Convert.ToInt16 | cast(a as signed) | - | - | - | +| Convert.ToInt32 | cast(a as signed) | - | - | - | +| Convert.ToInt64 | cast(a as signed) | - | - | - | +| Convert.ToSByte | cast(a as signed) | - | - | - | +| Convert.ToSingle | cast(a as char) | - | - | - | +| Convert.ToString | cast(a as decimal(14,7)) | - | - | - | +| Convert.ToUInt16 | cast(a as unsigned) | - | - | - | +| Convert.ToUInt32 | cast(a as unsigned) | - | - | - | +| Convert.ToUInt64 | cast(a as unsigned) | - | - | - | + # 更多文档整理中。。。