From b7e96620a70af053d00850512503dd682ebec74e Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 9 Sep 2022 01:38:24 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=E6=89=80=E6=9C=89?= =?UTF-8?q?=E5=9B=BD=E4=BA=A7=E6=95=B0=E6=8D=AE=E5=BA=93=E6=94=AF=E6=8C=81?= =?UTF-8?q?=20CustomMySql=E3=80=81CustomPostgreSQL=E3=80=81CustomOracle?= =?UTF-8?q?=E3=80=81CustomSqlServer=20=E8=87=AA=E5=AE=9A=E4=B9=89=E9=80=82?= =?UTF-8?q?=E9=85=8D=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.AggregateRoot.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 - .../FreeSql.Tests.Provider.Custom.csproj | 34 + .../FreeSql.Tests.Provider.Custom.xml | 113 + .../MySql/Curd/MySqlDeleteTest.cs | 104 + ...ySqlInsertOrUpdateIfExistsDoNothingTest.cs | 453 ++++ .../MySql/Curd/MySqlInsertOrUpdateTest.cs | 254 +++ .../MySql/Curd/MySqlInsertTest.cs | 162 ++ .../MySql/Curd/MySqlSelectTest.cs | 2009 +++++++++++++++++ .../MySql/Curd/MySqlUpdateTest.cs | 317 +++ .../MySql/Curd/OnDuplicateKeyUpdateTest.cs | 195 ++ .../MySql/MapType/BoolNullableTest.cs | 1722 ++++++++++++++ .../MySql/MapType/BoolTest.cs | 1130 +++++++++ .../MySql/MapType/DateTimeOffSetTest.cs | 62 + .../MySql/MapType/EnumTest.cs | 261 +++ .../MySql/MapType/ToStringTest.cs | 570 +++++ .../MySql/MySqlAdo/MySqlAdoTest.cs | 71 + .../MySql/MySqlAopTest.cs | 40 + .../MySql/MySqlCodeFirstTest.cs | 577 +++++ .../MySql/MySqlDbFirstTest.cs | 64 + .../MySql/MySqlExpression/ConvertTest.cs | 169 ++ .../MySql/MySqlExpression/DateTimeTest.cs | 720 ++++++ .../MySql/MySqlExpression/MathTest.cs | 156 ++ .../MySql/MySqlExpression/OtherTest.cs | 166 ++ .../MySql/MySqlExpression/StringTest.cs | 831 +++++++ .../MySql/MySqlExpression/TimeSpanTest.cs | 293 +++ .../Oracle/Curd/OracleDeleteTest.cs | 106 + ...acleInsertOrUpdateIfExistsDoNothingTest.cs | 425 ++++ .../Oracle/Curd/OracleInsertOrUpdateTest.cs | 467 ++++ .../Oracle/Curd/OracleInsertTest.cs | 278 +++ .../Oracle/Curd/OracleSelectTest.cs | 1872 +++++++++++++++ .../Oracle/Curd/OracleUpdateTest.cs | 191 ++ .../Oracle/MapType/BoolNullableTest.cs | 1571 +++++++++++++ .../Oracle/MapType/BoolTest.cs | 1105 +++++++++ .../Oracle/MapType/DateTimeOffSetTest.cs | 54 + .../Oracle/MapType/EnumTest.cs | 261 +++ .../Oracle/MapType/ToStringTest.cs | 570 +++++ .../Oracle/OracleAdo/OracleAdoTest.cs | 71 + .../Oracle/OracleAopTest.cs | 40 + .../Oracle/OracleCodeFirstTest.cs | 336 +++ .../Oracle/OracleDbFirstTest.cs | 65 + .../Oracle/OracleExpression/ConvertTest.cs | 169 ++ .../Oracle/OracleExpression/DateTimeTest.cs | 732 ++++++ .../Oracle/OracleExpression/MathTest.cs | 156 ++ .../Oracle/OracleExpression/OtherTest.cs | 165 ++ .../Oracle/OracleExpression/StringTest.cs | 827 +++++++ .../Oracle/OracleExpression/TimeSpanTest.cs | 293 +++ .../PostgreSQL/Curd/OnConflictDoUpdateTest.cs | 158 ++ .../PostgreSQL/Curd/PostgreSQLDeleteTest.cs | 105 + ...reSQLInsertOrUpdateIfExistsDoNotingTest.cs | 266 +++ .../Curd/PostgreSQLInsertOrUpdateTest.cs | 292 +++ .../PostgreSQL/Curd/PostgreSQLInsertTest.cs | 141 ++ .../PostgreSQL/Curd/PostgreSQLSelectTest.cs | 1932 ++++++++++++++++ .../PostgreSQL/Curd/PostgreSQLUpdateTest.cs | 185 ++ .../PostgreSQL/MapType/BoolNullableTest.cs | 1571 +++++++++++++ .../PostgreSQL/MapType/BoolTest.cs | 1105 +++++++++ .../PostgreSQL/MapType/DateTimeOffSetTest.cs | 54 + .../PostgreSQL/MapType/EnumTest.cs | 261 +++ .../PostgreSQL/MapType/ToStringTest.cs | 570 +++++ .../PostgreSQLAdo/PostgreSQLAdoTest.cs | 75 + .../PostgreSQL/PostgreSQLAopTest.cs | 40 + .../PostgreSQL/PostgreSQLCodeFirstTest.cs | 287 +++ .../PostgreSQL/PostgreSQLDbFirstTest.cs | 65 + .../PostgreSQLExpression/ConvertTest.cs | 169 ++ .../PostgreSQLExpression/DateTimeTest.cs | 732 ++++++ .../PostgreSQLExpression/MathTest.cs | 156 ++ .../PostgreSQLExpression/OtherTest.cs | 169 ++ .../PostgreSQLExpression/StringTest.cs | 829 +++++++ .../PostgreSQLExpression/TimeSpanTest.cs | 293 +++ .../SqlServer/Curd/SqlServerDeleteTest.cs | 112 + ...rverInsertOrUpdateIfExistsDoNothingTest.cs | 422 ++++ .../Curd/SqlServerInsertOrUpdateTest.cs | 464 ++++ .../SqlServer/Curd/SqlServerInsertTest.cs | 155 ++ .../SqlServer/Curd/SqlServerSelectTest.cs | 1819 +++++++++++++++ .../SqlServer/Curd/SqlServerUpdateTest.cs | 199 ++ .../SqlServer/MapType/BoolNullableTest.cs | 1572 +++++++++++++ .../SqlServer/MapType/BoolTest.cs | 1105 +++++++++ .../SqlServer/MapType/DateTimeOffSetTest.cs | 54 + .../SqlServer/MapType/EnumTest.cs | 263 +++ .../SqlServer/MapType/ToStringTest.cs | 571 +++++ .../SqlServerAdo/SqlServerAdoTest.cs | 98 + .../SqlServer/SqlServerAopTest.cs | 40 + .../SqlServer/SqlServerCodeFirstTest.cs | 485 ++++ .../SqlServer/SqlServerDbFirstTest.cs | 65 + .../SqlServerExpression/ConvertTest.cs | 169 ++ .../SqlServerExpression/DateTimeTest.cs | 349 +++ .../SqlServer/SqlServerExpression/MathTest.cs | 156 ++ .../SqlServerExpression/OtherTest.cs | 229 ++ .../SqlServerExpression/StringTest.cs | 392 ++++ .../SqlServerExpression/TimeSpanTest.cs | 210 ++ .../UnitTest1.cs | 1075 +++++++++ .../FreeSql.Tests.Provider.Custom/g.cs | 77 + FreeSql.sln | 18 +- FreeSql/DataType.cs | 4 +- FreeSql/FreeSqlBuilder.cs | 20 + .../FreeSql.Provider.Custom/CustomProvider.cs | 5 + .../FreeSqlCustomGlobalExtensions.cs | 39 + .../MySql/Curd/CustomMySqlDelete.cs | 121 + .../MySql/Curd/CustomMySqlInsert.cs | 201 ++ .../MySql/Curd/CustomMySqlInsertOrUpdate.cs | 88 + .../Curd/CustomMySqlOnDuplicateKeyUpdate.cs | 168 ++ .../MySql/Curd/CustomMySqlSelect.cs | 212 ++ .../MySql/Curd/CustomMySqlUpdate.cs | 170 ++ .../MySql/CustomMySqlAdo/CustomMySqlAdo.cs | 68 + .../MySql/CustomMySqlCodeFirst.cs | 408 ++++ .../MySql/CustomMySqlDbFirst.cs | 457 ++++ .../MySql/CustomMySqlExpression.cs | 563 +++++ .../MySql/CustomMySqlProvider.cs | 46 + .../MySql/CustomMySqlUtils.cs | 113 + .../Oracle/Curd/CustomOracleDelete.cs | 26 + .../Oracle/Curd/CustomOracleInsert.cs | 224 ++ .../Oracle/Curd/CustomOracleInsertOrUpdate.cs | 74 + .../Oracle/Curd/CustomOracleSelect.cs | 232 ++ .../Oracle/Curd/CustomOracleUpdate.cs | 74 + .../Oracle/CustomOracleAdo/CustomOracleAdo.cs | 81 + .../Oracle/CustomOracleCodeFirst.cs | 503 +++++ .../Oracle/CustomOracleDbFirst.cs | 584 +++++ .../Oracle/CustomOracleExpression.cs | 569 +++++ .../Oracle/CustomOracleProvider.cs | 51 + .../Oracle/CustomOracleUtils.cs | 133 ++ .../PostgreSQL/Curd/CustomPostgreSQLDelete.cs | 121 + .../PostgreSQL/Curd/CustomPostgreSQLInsert.cs | 217 ++ .../Curd/CustomPostgreSQLInsertOrUpdate.cs | 72 + .../CustomPostgreSQLOnConflictDoUpdate.cs | 209 ++ .../PostgreSQL/Curd/CustomPostgreSQLSelect.cs | 214 ++ .../PostgreSQL/Curd/CustomPostgreSQLUpdate.cs | 187 ++ .../CustomPostgreSQLAdo.cs | 70 + .../PostgreSQL/CustomPostgreSQLCodeFirst.cs | 480 ++++ .../PostgreSQL/CustomPostgreSQLDbFirst.cs | 554 +++++ .../PostgreSQL/CustomPostgreSQLExpression.cs | 658 ++++++ .../PostgreSQL/CustomPostgreSQLProvider.cs | 45 + .../PostgreSQL/CustomPostgreSQLUtils.cs | 168 ++ .../SqlServer/Curd/CustomSqlServerDelete.cs | 133 ++ .../SqlServer/Curd/CustomSqlServerInsert.cs | 191 ++ .../Curd/CustomSqlServerInsertOrUpdate.cs | 78 + .../SqlServer/Curd/CustomSqlServerSelect.cs | 369 +++ .../SqlServer/Curd/CustomSqlServerUpdate.cs | 173 ++ .../CustomSqlServerAdo/CustomSqlServerAdo.cs | 83 + .../SqlServer/CustomSqlServerCodeFirst.cs | 499 ++++ .../SqlServer/CustomSqlServerDbFirst.cs | 521 +++++ .../SqlServer/CustomSqlServerExpression.cs | 558 +++++ .../SqlServer/CustomSqlServerProvider.cs | 57 + .../SqlServer/CustomSqlServerUtils.cs | 109 + Providers/FreeSql.Provider.Custom/readme.md | 41 +- .../FreeSqlOdbcGlobalExtensions.cs | 14 +- Providers/FreeSql.Provider.Odbc/readme.md | 10 +- 146 files changed, 50828 insertions(+), 29 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/FreeSql.Tests.Provider.Custom.csproj create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/FreeSql.Tests.Provider.Custom.xml create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlDeleteTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlInsertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlSelectTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/OnDuplicateKeyUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/BoolNullableTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/BoolTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/EnumTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/ToStringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlAdo/MySqlAdoTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlCodeFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlDbFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/ConvertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/DateTimeTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/MathTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/OtherTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/StringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/TimeSpanTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleDeleteTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleInsertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleSelectTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/BoolNullableTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/BoolTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/EnumTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/ToStringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleAdo/OracleAdoTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleCodeFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleDbFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/ConvertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/DateTimeTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/MathTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/OtherTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/StringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/TimeSpanTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/OnConflictDoUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLDeleteTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLInsertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLSelectTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/BoolNullableTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/BoolTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/EnumTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/ToStringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLCodeFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLDbFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/ConvertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/MathTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/OtherTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/StringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerDeleteTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerInsertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerSelectTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerUpdateTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/BoolNullableTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/BoolTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/DateTimeOffSetTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/EnumTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/ToStringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerAdo/SqlServerAdoTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerAopTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerCodeFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerDbFirstTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/ConvertTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/DateTimeTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/MathTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/OtherTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/StringTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/TimeSpanTest.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/UnitTest1.cs create mode 100644 FreeSql.Tests/FreeSql.Tests.Provider.Custom/g.cs create mode 100644 Providers/FreeSql.Provider.Custom/FreeSqlCustomGlobalExtensions.cs create mode 100644 Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlDelete.cs create mode 100644 Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlInsert.cs create mode 100644 Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlOnDuplicateKeyUpdate.cs create mode 100644 Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlSelect.cs create mode 100644 Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlUpdate.cs create mode 100644 Providers/FreeSql.Provider.Custom/MySql/CustomMySqlAdo/CustomMySqlAdo.cs create mode 100644 Providers/FreeSql.Provider.Custom/MySql/CustomMySqlCodeFirst.cs create mode 100644 Providers/FreeSql.Provider.Custom/MySql/CustomMySqlDbFirst.cs create mode 100644 Providers/FreeSql.Provider.Custom/MySql/CustomMySqlExpression.cs create mode 100644 Providers/FreeSql.Provider.Custom/MySql/CustomMySqlProvider.cs create mode 100644 Providers/FreeSql.Provider.Custom/MySql/CustomMySqlUtils.cs create mode 100644 Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleDelete.cs create mode 100644 Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleInsert.cs create mode 100644 Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleSelect.cs create mode 100644 Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleUpdate.cs create mode 100644 Providers/FreeSql.Provider.Custom/Oracle/CustomOracleAdo/CustomOracleAdo.cs create mode 100644 Providers/FreeSql.Provider.Custom/Oracle/CustomOracleCodeFirst.cs create mode 100644 Providers/FreeSql.Provider.Custom/Oracle/CustomOracleDbFirst.cs create mode 100644 Providers/FreeSql.Provider.Custom/Oracle/CustomOracleExpression.cs create mode 100644 Providers/FreeSql.Provider.Custom/Oracle/CustomOracleProvider.cs create mode 100644 Providers/FreeSql.Provider.Custom/Oracle/CustomOracleUtils.cs create mode 100644 Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLDelete.cs create mode 100644 Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLInsert.cs create mode 100644 Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLOnConflictDoUpdate.cs create mode 100644 Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLSelect.cs create mode 100644 Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLUpdate.cs create mode 100644 Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLAdo/CustomPostgreSQLAdo.cs create mode 100644 Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLCodeFirst.cs create mode 100644 Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLDbFirst.cs create mode 100644 Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLExpression.cs create mode 100644 Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLProvider.cs create mode 100644 Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLUtils.cs create mode 100644 Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerDelete.cs create mode 100644 Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerInsert.cs create mode 100644 Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerInsertOrUpdate.cs create mode 100644 Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerSelect.cs create mode 100644 Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerUpdate.cs create mode 100644 Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerAdo/CustomSqlServerAdo.cs create mode 100644 Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerCodeFirst.cs create mode 100644 Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerDbFirst.cs create mode 100644 Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerExpression.cs create mode 100644 Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerProvider.cs create mode 100644 Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerUtils.cs diff --git a/Extensions/FreeSql.Extensions.AggregateRoot/FreeSql.Extensions.AggregateRoot.csproj b/Extensions/FreeSql.Extensions.AggregateRoot/FreeSql.Extensions.AggregateRoot.csproj index 492b0057..f939fc97 100644 --- a/Extensions/FreeSql.Extensions.AggregateRoot/FreeSql.Extensions.AggregateRoot.csproj +++ b/Extensions/FreeSql.Extensions.AggregateRoot/FreeSql.Extensions.AggregateRoot.csproj @@ -18,7 +18,7 @@ true key.snk false - 1.0.0 + 1.0.1 diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 26522f10..537315e2 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -800,14 +800,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/FreeSql.Tests.Provider.Custom.csproj b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/FreeSql.Tests.Provider.Custom.csproj new file mode 100644 index 00000000..a78f9598 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/FreeSql.Tests.Provider.Custom.csproj @@ -0,0 +1,34 @@ + + + + net6.0 + false + + + + FreeSql.Tests.Provider.Custom.xml + 3 + 1701;1702;1591 + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/FreeSql.Tests.Provider.Custom.xml b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/FreeSql.Tests.Provider.Custom.xml new file mode 100644 index 00000000..955c95c6 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/FreeSql.Tests.Provider.Custom.xml @@ -0,0 +1,113 @@ + + + + FreeSql.Tests.Provider.Custom + + + + + 保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert + + + + + 表中带点 + + + + + 主键 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 类型 + + + + + 内容简介 + + + + + 缩略图 + + + + + 点击量 + + + + + + + + + + + + + + + + + + + + + + + + + 测试中文重命名id + + + + + 姓名 + + + + + 试卷表 + + + + + 考核计划ID + + + + + 总分 + + + + diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlDeleteTest.cs new file mode 100644 index 00000000..19b06e8c --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlDeleteTest.cs @@ -0,0 +1,104 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.MySql +{ + public class MySqlDeleteTest + { + + IDelete delete => g.mysql.Delete(); //�������� + + [Table(Name = "tb_topic_delete")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.mysql.Delete().ToSql()); + var sql = g.mysql.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` IN (1,2))", sql); + + sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); + + sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` IN (1,2))", sql); + + sql = g.mysql.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); + + sql = g.mysql.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM `MultiPkTopic` WHERE (`Id1` = 1 AND `Id2` = 10 OR `Id1` = 2 AND `Id2` = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); + + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (id = @id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM `tb_topic_delete` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + + var id = g.mysql.Insert(new Topic { Title = "xxxx" }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { + + //delete.Where(a => a.Id > 0).ExecuteDeleted(); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.mysql.Delete().ToSql()); + var sql = g.mysql.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` IN (1,2))", sql); + + sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); + + sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` IN (1,2))", sql); + + sql = g.mysql.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM `TopicAsTable` WHERE (`Id` = 1)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..a9b9c19e --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,453 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.MySql +{ + public class MySqlInsertOrUpdateIfExistsDoNothingTest + { + + IFreeSql fsql => g.mysql; + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb02`(`id`, `name`) SELECT 1, '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb02` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`name`) VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb022`(`id`, `name`) SELECT 1, '100001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '100002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '100003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '100004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb022` a + WHERE (a.`id` = 4) + limit 0,1) + +; + +INSERT INTO `tbioudb022`(`name`) VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '011' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 2, '02', '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '01' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '02' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '03' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '04' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb03`(`id1`, `id2`, `name`) SELECT 1, '01', '001' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 1 AND a.`id2` = '01') + limit 0,1) +UNION ALL + SELECT 2, '02', '002' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 2 AND a.`id2` = '02') + limit 0,1) +UNION ALL + SELECT 3, '03', '003' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 3 AND a.`id2` = '03') + limit 0,1) +UNION ALL + SELECT 4, '04', '004' + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb03` a + WHERE (a.`id1` = 4 AND a.`id2` = '04') + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '011', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 2, '02', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '01', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '02', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '03', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '04', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbioudb04`(`id`, `name`, `version`, `CreateTime`) SELECT 1, '001', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 1) + limit 0,1) +UNION ALL + SELECT 2, '002', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 2) + limit 0,1) +UNION ALL + SELECT 3, '003', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 3) + limit 0,1) +UNION ALL + SELECT 4, '004', 0, now(3) + FROM dual WHERE NOT EXISTS(SELECT 1 + FROM `tbioudb04` a + WHERE (a.`id` = 4) + limit 0,1)", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlInsertOrUpdateTest.cs new file mode 100644 index 00000000..0bb8f628 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlInsertOrUpdateTest.cs @@ -0,0 +1,254 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.MySql +{ + public class MySqlInsertOrUpdateTest + { + + IFreeSql fsql => g.mysql; + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(1, '01') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(1, '011') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(2, '02') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou02`(`id`, `name`) VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '01') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '011') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(2, '02') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`name`) VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou022`(`id`, `name`) VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`) + +; + +INSERT INTO `tbiou022`(`name`) VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(12, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(1, '01', '01') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(1, '01', '011') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(2, '02', '02') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou03`(`id1`, `id2`, `name`) VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004') +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`)", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(1, '01', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(1, '011', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(2, '02', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(1, '01', 0, now(3)), (2, '02', 0, now(3)), (3, '03', 0, now(3)), (4, '04', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO `tbiou04`(`id`, `name`, `version`, `CreateTime`) VALUES(1, '001', 0, now(3)), (2, '002', 0, now(3)), (3, '003', 0, now(3)), (4, '004', 0, now(3)) +ON DUPLICATE KEY UPDATE +`name` = VALUES(`name`), +`version` = `version` + 1", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlInsertTest.cs new file mode 100644 index 00000000..14e91a10 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlInsertTest.cs @@ -0,0 +1,162 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.MySql +{ + public class MySqlInsertTest + { + + IInsert insert => g.mysql.Insert(); //�������� + + [Table(Name = "tb_topic_insert")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestEnumInsertTb + { + [Column(IsIdentity = true)] + public int id { get; set; } + public TestEnumInserTbType type { get; set; } + public DateTime time { get; set; } = new DateTime(); + } + enum TestEnumInserTbType { str1, biggit, sum211 } + + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`, `CreateTime`) VALUES(0, 'newtitle0', '0001-01-01 00:00:00.000')", sql); + + sql = insert.AppendData(items).ToSql(); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`, `CreateTime`) VALUES(0, 'newtitle0', '0001-01-01 00:00:00.000'), (100, 'newtitle1', '0001-01-01 00:00:00.000'), (200, 'newtitle2', '0001-01-01 00:00:00.000'), (300, 'newtitle3', '0001-01-01 00:00:00.000'), (400, 'newtitle4', '0001-01-01 00:00:00.000'), (500, 'newtitle5', '0001-01-01 00:00:00.000'), (600, 'newtitle6', '0001-01-01 00:00:00.000'), (700, 'newtitle7', '0001-01-01 00:00:00.000'), (800, 'newtitle8', '0001-01-01 00:00:00.000'), (900, 'newtitle9', '0001-01-01 00:00:00.000')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Title`) VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + + sql = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211, time = DateTime.Parse("2019-09-19 21:26:51.030") }).ToSql(); + Assert.Equal("INSERT INTO `TestEnumInsertTb`(`type`, `time`) VALUES('sum211', '2019-09-19 21:26:51.030')", sql); + + sql = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ToSql(); + Assert.Equal("INSERT INTO `TestEnumInsertTb`(`type`, `time`) VALUES('sum211', '0001-01-01 00:00:00.000')", sql); + } + + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Title`) VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`, `Title`) VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal("INSERT INTO `tb_topic_insert`(`Clicks`) VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + + g.mysql.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.mysql.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.mysql.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topic_insertIgnoreColumns")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + + Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteAffrows()); + Assert.Equal(1, g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + + var id = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).ExecuteIdentity(); + Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + id = g.mysql.Insert().AppendData(new TestEnumInsertTb { type = TestEnumInserTbType.sum211 }).NoneParameter().ExecuteIdentity(); + Assert.Equal(TestEnumInserTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + } + [Fact] + public void ExecuteInserted() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + //insert.AppendData(items.First()).ExecuteInserted(); + } + + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(0, 'newTitle0', '0001-01-01 00:00:00.000')", sql); + + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`, `CreateTime`) VALUES(0, 'newTitle0', '0001-01-01 00:00:00.000'), (100, 'newTitle1', '0001-01-01 00:00:00.000'), (200, 'newTitle2', '0001-01-01 00:00:00.000'), (300, 'newTitle3', '0001-01-01 00:00:00.000'), (400, 'newTitle4', '0001-01-01 00:00:00.000'), (500, 'newTitle5', '0001-01-01 00:00:00.000'), (600, 'newTitle6', '0001-01-01 00:00:00.000'), (700, 'newTitle7', '0001-01-01 00:00:00.000'), (800, 'newTitle8', '0001-01-01 00:00:00.000'), (900, 'newTitle9', '0001-01-01 00:00:00.000')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES('newTitle0'), ('newTitle1'), ('newTitle2'), ('newTitle3'), ('newTitle4'), ('newTitle5'), ('newTitle6'), ('newTitle7'), ('newTitle8'), ('newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Title`) VALUES('newTitle0'), ('newTitle1'), ('newTitle2'), ('newTitle3'), ('newTitle4'), ('newTitle5'), ('newTitle6'), ('newTitle7'), ('newTitle8'), ('newTitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`, `Title`) VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO `Topic_InsertAsTable`(`Clicks`) VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlSelectTest.cs new file mode 100644 index 00000000..279772e8 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlSelectTest.cs @@ -0,0 +1,2009 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.MySql +{ + + public class MySqlSelectTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + public class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + [Column(OldName = "TypeGuid")] + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + + public virtual TopicFields Fields { get; set; } + } + public class TopicFields + { + [Column(IsPrimary = true)] + public int TopicId { get; set; } + public virtual Topic Topic { get; set; } + } + public class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + + public int ParentId { get; set; } + public virtual TestTypeParentInfo Parent { get; set; } + + public string Name { get; set; } + + public virtual ICollection Topics { get; set; } + } + public class TestTypeParentInfo + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.mysql.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.mysql.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.mysql.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.mysql.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.mysql.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, g.mysql.Insert().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, g.mysql.Insert().AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.mysql.Insert(items).ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, 111222"); + var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + var testDto5 = select.Limit(10).ToList(); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + var testDto55 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + + var t0 = select.Limit(50).ToList(); + + + 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(); + + + var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToSql(); + var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToSql(); + var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToSql(); + + //g.mysql.Select().Join((a, b, c) => new Model.JoinResult3( + // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, + // Model.JoinType.InnerJoin, c.Id == b.ParentId && c.Name == "xxx") + //); + + //var sql4 = select.From((a, b, c) => new SelectFrom() + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) + //.Where(a => a.Id == 1).ToSql(); + + var sql4 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name == "xxx")).ToSql(); + //.Where(a => a.Id == 1).ToSql(); + + + var list111 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name != "xxx")); + var list111sql = list111.ToSql(); + var list111data = list111.ToList((a, b, c) => new + { + a.Id, + title_substring = a.Title.Substring(0, 1), + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + }); + + var ttt122 = g.mysql.Select().Where(a => a.Id > 0).ToSql(); + var sql5 = g.mysql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToSql(); + var t11112 = g.mysql.Select().ToList(a => new + { + a.Id, + a.Title, + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + + }); + + var t100 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + var t101 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + + + var t1111 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type }); + + var t2222 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type.Name }); + + g.mysql.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.mysql.Select().ToList(); + var testGuidId6 = g.mysql.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.mysql.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.mysql.GetRepository(); + repo.DbContextOptions.EnableCascadeSave = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.mysql.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Single(ddd); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Fact] + public void ToDictionary() + { + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.mysql.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + g.mysql.Insert().AppendData(new testenumWhere { type = testenumWhereType.Blaaa }).ExecuteAffrows(); + + var sql1 = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToSql(); + var sql2 = g.mysql.Select().Where(a => testenumWhereType.Blaaa == a.type).ToSql(); + + var sql3 = g.mysql.Select().Where(a => a.type.Equals(testenumWhereType.Blaaa)).ToSql(); + var tolist = g.mysql.Select().Where(a => a.type == testenumWhereType.Blaaa).ToList(); + } + class testenumWhere + { + public Guid id { get; set; } + public testenumWhereType type { get; set; } + } + public enum testenumWhereType { Menu, Class, Blaaa } + + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid`", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` INNER JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` INNER JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` INNER JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid`", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` RIGHT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` RIGHT JOIN `TestTypeParentInfo` c ON c.`Id` = a__Type.`ParentId`", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN `TestTypeInfo` b ON a.`TypeGuid` = b.`Guid` RIGHT JOIN `TestTypeParentInfo` c ON b.`ParentId` = c.`Id`", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + + } + [Fact] + public void Where() + { + + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������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`, a.`Clicks`, a.`TypeGuid`, 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`, a.`Clicks`, a.`TypeGuid`, 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`, a.`Clicks`, a.`TypeGuid`, 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`, a.`Clicks`, a.`TypeGuid`, 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.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TypeGuid`)", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Name` = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Guid` = a.`TypeGuid` AND b.`Name` = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b WHERE (b.`Name` = 'typeTitle' AND b.`Guid` = a.`TypeGuid`)", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeParentInfo` c WHERE (c.`Name` = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); + query2.ToList(); + + } + [Fact] + public void WhereIf() + { + //����е�������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`, a.`Clicks`, a.`TypeGuid`, 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`, a.`Clicks`, a.`TypeGuid`, 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`, a.`Clicks`, a.`TypeGuid`, 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`, a.`Clicks`, a.`TypeGuid`, 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.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` WHERE (a__Type.`Name` = 'typeTitle' AND a__Type.`Guid` = a.`TypeGuid`)", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topic` a LEFT JOIN `TestTypeInfo` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfo` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Name` = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .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`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c WHERE (a.`Id` = 10 AND c.`Name` = 'xxx') AND (b.`ParentId` = 20)", sql); + query2.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, 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`, a.`Clicks`, a.`TypeGuid`, 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`, a.`Clicks`, a.`TypeGuid`, 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`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, 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`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .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`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a, `TestTypeInfo` b, `TestTypeParentInfo` c", sql); + query2.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .Count(out var trycount) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.mysql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.mysql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + + [Fact] + public void OrderBy() + { + var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void OrderByRandom() + { + var t1 = select.OrderByRandom().Limit(10).ToSql("1"); + Assert.Equal(@"SELECT 1 +FROM `tb_topic` a +ORDER BY rand() +limit 0,10", t1); + var t2 = select.OrderByRandom().Limit(10).ToList(); + } + + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).Limit(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + var subquery = select.ToSql(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, ifnull((SELECT sum(b.`Id`) + FROM `tb_topic` b), 0) as6 +FROM `tb_topic` a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + } + [Fact] + public void Min() + { + var subquery = select.ToSql(a => new + { + all = a, + min = select.As("b").Min(b => b.Id), + min2 = select.As("b").Min(b => b.CreateTime) + }); + Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, ifnull((SELECT min(b.`Id`) + FROM `tb_topic` b), 0) as6, ifnull((SELECT min(b.`CreateTime`) + FROM `tb_topic` b), '0001-01-01 00:00:00.000') as7 +FROM `tb_topic` a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + min = select.As("b").Min(b => b.Id), + min2 = select.As("b").Min(b => b.CreateTime) + }); + } + [Fact] + public void Max() + { + var subquery = select.ToSql(a => new + { + all = a, + max = select.As("b").Max(b => b.Id), + max2 = select.As("b").Max(b => b.CreateTime) + }); + Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, ifnull((SELECT max(b.`Id`) + FROM `tb_topic` b), 0) as6, ifnull((SELECT max(b.`CreateTime`) + FROM `tb_topic` b), '0001-01-01 00:00:00.000') as7 +FROM `tb_topic` a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + max = select.As("b").Max(b => b.Id), + max2 = select.As("b").Max(b => b.CreateTime) + }); + } + [Fact] + public void Avg() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + Assert.Equal(@"SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5, ifnull((SELECT avg(b.`Id`) + FROM `tb_topic` b), 0) as6 +FROM `tb_topic` a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + } + [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` +FROM `tb_topic` a +WHERE (((cast(a.`Id` as char)) in (SELECT b.`Title` + FROM `tb_topic` b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + + subquery = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` +FROM `tb_topic` a +WHERE (((cast(a.`Id` as char)) in ( SELECT * FROM (SELECT b.`Title` + FROM `tb_topic` b + limit 0,10) ftblmt50 )))", subquery); + subqueryList = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (type == typeof(Topic)) return oldname + "AsTable1"; + else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; + return oldname + "AsTable"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid`", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` AND a__Type.`Name` = 'xxx' LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid`", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx'", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` AND b.`Name` = 'xxx' LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId` WHERE (a__Type__Parent.`Id` = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a__Type.`Guid`, a__Type.`ParentId`, a__Type.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` a__Type__Parent ON a__Type__Parent.`Id` = a__Type.`ParentId`", sql); + + query = select + .LeftJoin((a, b) => b.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` a__Type ON a__Type.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeInfoAsTable2` b ON b.`Guid` = a.`TypeGuid` LEFT JOIN `TestTypeParentInfoAsTable` c ON c.`Id` = a__Type.`ParentId`", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, b.`Guid`, b.`ParentId`, b.`Name`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN `TestTypeInfoAsTable2` b ON a.`TypeGuid` = b.`Guid` LEFT JOIN `TestTypeParentInfoAsTable` c ON b.`ParentId` = c.`Id`", sql); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topicAsTable1` a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = ?bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb UNION ALL SELECT * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM `tb_topic` a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); + + var sqltmp12 = g.mysql.Select() + .Where(t => t.IsFinished && (t.AuditorId == "1" || t.AuditorId == "1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3")) + .GroupBy(t => new { t.ProcessId, t.NodeId, t.NodeName }) + .ToSql(t => new WF_TaskGroupBy + { + TaskId = t.Max(t.Value.Id), + TaskType = t.Max(t.Value.Type), + ProcessId = t.Key.ProcessId, + NodeId = t.Key.NodeId, + NodeName = t.Key.NodeName + }, FieldAliasOptions.AsProperty); + + var groupsql12 = g.mysql.Select() + .AsTable((type, old) => type == typeof(WF_TaskGroupBy) ? $"( {sqltmp12} )" : null) + .LeftJoin((a, p) => p.Id == a.ProcessId) + .Where((a, p) => (p.IsFinished || a.TaskType == 3) && p.EnabledMark) + .ToSql((a, p) => new + { + WF_Task = a, + WF_ProcessInstance = p + }); + + Assert.Equal(@"SELECT max(a.`Id`) `TaskId`, max(a.`Type`) `TaskType`, a.`ProcessId`, a.`NodeId`, a.`NodeName` +FROM `WF_Task` a +WHERE (a.`IsFinished` = 1 AND (a.`AuditorId` = '1' OR a.`AuditorId` = '1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3')) +GROUP BY a.`ProcessId`, a.`NodeId`, a.`NodeName`", sqltmp12); + Assert.Equal(@"SELECT a.`TaskId` as1, a.`TaskType` as2, a.`ProcessId` as3, a.`NodeId` as4, a.`NodeName` as5, b.`Id` as6, b.`TaskType` as7, b.`ProcessId` as8, b.`NodeId` as9, b.`CreateTime` as10, b.`IsFinished` as11, b.`EnabledMark` as12 +FROM ( SELECT max(a.`Id`) `TaskId`, max(a.`Type`) `TaskType`, a.`ProcessId`, a.`NodeId`, a.`NodeName` + FROM `WF_Task` a + WHERE (a.`IsFinished` = 1 AND (a.`AuditorId` = '1' OR a.`AuditorId` = '1cb71584-a6dd-4b26-8c88-ed9fb8cf87a3')) + GROUP BY a.`ProcessId`, a.`NodeId`, a.`NodeName` ) a +LEFT JOIN `WF_ProcessInstance` b ON b.`Id` = a.`ProcessId` +WHERE ((b.`IsFinished` = 1 OR a.`TaskType` = 3) AND b.`EnabledMark` = 1)", groupsql12); + + var grouplist12 = g.mysql.Select() + .AsTable((type, old) => type == typeof(WF_TaskGroupBy) ? $"( {sqltmp12} )" : null) + .LeftJoin((a, p) => p.Id == a.ProcessId) + .Where((a, p) => (p.IsFinished || a.TaskType == 3) && p.EnabledMark) + .ToList((a, p) => new + { + WF_Task = a, + WF_ProcessInstance = p + }); + } + + [Table(DisableSyncStructure = true)] + class WF_TaskGroupBy + { + public int TaskId { get; set; } + public int TaskType { get; set; } + public int ProcessId { get; set; } + public int NodeId { get; set; } + public string NodeName { get; set; } + } + class WF_Task + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int Type { get; set; } + public int ProcessId { get; set; } + public int NodeId { get; set; } + public string NodeName { get; set; } + public string AuditorId { get; set; } + public DateTime CreateTime { get; set; } + public bool IsFinished { get; set; } + } + class WF_ProcessInstance + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int TaskType { get; set; } + public int ProcessId { get; set; } + public int NodeId { get; set; } + public DateTime CreateTime { get; set; } + public bool IsFinished { get; set; } + public bool EnabledMark { get; set; } + } + + public class TestInclude_OneToManyModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TestInclude_OneToManyModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TestInclude_OneToManyModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TestInclude_OneToManyModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TestInclude_OneToManyModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TestInclude_OneToManyModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.mysql.Insert(model1).ExecuteIdentity(); + var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.mysql.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.mysql.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.mysql.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.mysql.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.mysql.Insert(model4s).ExecuteAffrows()); + + var t0 = g.mysql.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.mysql.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + //---- Select ---- + + var at0 = g.mysql.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.mysql.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.mysql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TestInclude_OneToManyModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TestInclude_OneToManyModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TestInclude_OneToManyModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } + public List childs { get; set; } + } + public class TestInclude_OneToManyModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; + model2.id = (int)g.mysql.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.mysql.Insert(model3s).ExecuteAffrows()); + + var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.mysql.Insert(model1).ExecuteIdentity(); + + var t1 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + //---- Select ---- + + var at1 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.mysql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.mysql.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.mysql.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.mysql.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.mysql.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.mysql.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.mysql.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.mysql.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.mysql.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.mysql.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.mysql.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + // --- Select --- + + var atags0 = g.mysql.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.mysql.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.mysql.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.mysql.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.mysql.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.mysql.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.mysql.Insert(song3).ExecuteIdentity(); + + g.mysql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.mysql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.mysql.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.mysql.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.mysql, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.mysql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.mysql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.mysql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.mysql.Select().Count()); + Assert.Equal(3, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.mysql.Select().Count()); + Assert.Equal(3, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.mysql.Select().Count()); + Assert.Equal(3, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.mysql.Select().Count()); + Assert.Equal(5, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.mysql.Select().Count()); + Assert.Equal(5, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.mysql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.mysql.Select().Count()); + g.mysql.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.mysql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.mysql.Select().Count()); + Assert.Equal(5, g.mysql.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + [Fact] + public void ForUpdate() + { + var orm = g.mysql; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`id`, a.`name` FROM `ToUpd1Pk` a limit 0,1 for update", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.`id`, a.`name` FROM `ToUpd1Pk` a limit 0,1 for update", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } + + [Fact] + public void ToTreeList() + { + var fsql = g.mysql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableCascadeSave = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + //t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); + //Assert.Single(t3); + //Assert.Equal("100000", t3[0].Code); + //Assert.Single(t3[0].Childs); + //Assert.Equal("110000", t3[0].Childs[0].Code); + //Assert.Equal(2, t3[0].Childs[0].Childs.Count); + //Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + //Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + //t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); + //Assert.Equal(4, t3.Count); + //Assert.Equal("100000", t3[0].Code); + //Assert.Equal("110000", t3[1].Code); + //Assert.Equal("110100", t3[2].Code); + //Assert.Equal("110101", t3[3].Code); + + //t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); + //Assert.Equal(3, t3.Count); + //Assert.Equal("110000", t3[0].Code); + //Assert.Equal("110100", t3[1].Code); + //Assert.Equal("110101", t3[2].Code); + + //var select = fsql.Select() + // .Where(a => a.Name == "中国") + // .AsTreeCte() + // //.OrderBy("a.cte_level desc") //递归层级 + // ; + //// var list = select.ToList(); //自己调试看查到的数据 + //select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + //Assert.Equal(855, fsql.Select() + // .Where(a => a.Name == "中国") + // .AsTreeCte().Distinct().First(a => a.testint)); + + //Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + //Assert.False(fsql.Select() + // .Where(a => a.Name == "中国") + // .AsTreeCte().Any()); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + + public int testint { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlUpdateTest.cs new file mode 100644 index 00000000..dc64233f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/MySqlUpdateTest.cs @@ -0,0 +1,317 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.MySql +{ + public class MySqlUpdateTest + { + IUpdate update => g.mysql.Update(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestEnumUpdateTb + { + [Column(IsIdentity = true)] + public int id { get; set; } + public TestEnumUpdateTbType type { get; set; } + public DateTime time { get; set; } = new DateTime(); + } + enum TestEnumUpdateTbType { str1, biggit, sum211 } + + [Fact] + public void Dywhere() + { + Assert.Null(g.mysql.Update().ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test' \r\nWHERE (`Id` IN (1,2))", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` IN (1,2))", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE `tb_topic` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } + + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = NULL, `Title` = 'newtitle', `CreateTime` = '0001-01-01 00:00:00.000' WHERE (`Id` = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; + + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = CASE `Id` WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END, `Title` = CASE `Id` WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END, `CreateTime` = CASE `Id` WHEN 1 THEN '0001-01-01 00:00:00.000' WHEN 2 THEN '0001-01-01 00:00:00.000' WHEN 3 THEN '0001-01-01 00:00:00.000' WHEN 4 THEN '0001-01-01 00:00:00.000' WHEN 5 THEN '0001-01-01 00:00:00.000' WHEN 6 THEN '0001-01-01 00:00:00.000' WHEN 7 THEN '0001-01-01 00:00:00.000' WHEN 8 THEN '0001-01-01 00:00:00.000' WHEN 9 THEN '0001-01-01 00:00:00.000' WHEN 10 THEN '0001-01-01 00:00:00.000' END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = CASE `Id` WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `CreateTime` = '2020-01-01 00:00:00.000' WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("INSERT INTO `TestEnumUpdateTb`(`type`, `time`) VALUES('sum211', '0001-01-01 00:00:00.000')", sql); + var id = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); + Assert.True(id > 0); + Assert.Equal(TestEnumUpdateTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + + sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211', `time` = '0001-01-01 00:00:00.000' WHERE (`id` = 0)", sql); + g.mysql.Update().SetSource(new TestEnumUpdateTb { id = (int)id, type = TestEnumUpdateTbType.biggit }).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + + sql = g.mysql.Insert().NoneParameter().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("INSERT INTO `TestEnumUpdateTb`(`type`, `time`) VALUES('sum211', '0001-01-01 00:00:00.000')", sql); + id = g.mysql.Insert().NoneParameter().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); + Assert.True(id > 0); + Assert.Equal(TestEnumUpdateTbType.sum211, g.mysql.Select().Where(a => a.id == id).First()?.type); + + sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211', `time` = '0001-01-01 00:00:00.000' WHERE (`id` = 0)", sql); + g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { id = (int)id, type = TestEnumUpdateTbType.biggit }).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + + sql = g.mysql.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } + } + [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE `tssi01` SET `tint` = 10 WHERE (`id` = '00000000-0000-0000-0000-000000000000')", + g.mysql.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = 'newtitle' WHERE (`Id` = 1)", sql); + + sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).IgnoreColumns(a => a.time).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + + sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).IgnoreColumns(a => a.time).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = 'newtitle' WHERE (`Id` = 1)", sql); + + sql = g.mysql.Update().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).UpdateColumns(a => a.type).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + + sql = g.mysql.Update().NoneParameter().SetSource(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).UpdateColumns(a => a.type).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = 'newtitle' WHERE (`Id` = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Title` = 'newtitle', `CreateTime` = '2020-01-01 00:00:00.000' WHERE (`Id` = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 div 1 WHERE (`Id` = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = ifnull(`Clicks`, 0) * 10 div 1 WHERE (`Id` = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Id` = (`Id` - 10) WHERE (`Id` = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = `Clicks` * 10 div 1 WHERE (`Id` = 1)", sql); + + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = case when `CreateTime` > '2000-01-01 00:00:00.000' then 1 else 2 end WHERE (`Id` = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Id` = 10 WHERE (`Id` = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = NULL WHERE (`Id` = 1)", sql); + + var id = g.mysql.Insert().AppendData(new TestEnumUpdateTb { type = TestEnumUpdateTbType.sum211 }).ExecuteIdentity(); + Assert.True(id > 0); + sql = g.mysql.Update().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.biggit).ToSql().Replace("\r\n", ""); + Assert.Equal($"UPDATE `TestEnumUpdateTb` SET `type` = 'biggit' WHERE (`id` = {id})", sql); + g.mysql.Update().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.biggit).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.biggit, g.mysql.Select().Where(a => a.id == id).First()?.type); + + sql = g.mysql.Update().NoneParameter().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.str1).ToSql().Replace("\r\n", ""); + Assert.Equal($"UPDATE `TestEnumUpdateTb` SET `type` = 'str1' WHERE (`id` = {id})", sql); + g.mysql.Update().NoneParameter().Where(a => a.id == id).Set(a => a.type, TestEnumUpdateTbType.str1).ExecuteAffrows(); + Assert.Equal(TestEnumUpdateTbType.str1, g.mysql.Select().Where(a => a.id == id).First()?.type); + } + public class tenumcls + { + public Guid id { get; set; } + public tenum status { get; set; } + } + public enum tenum + { + WaitPay = 1, + Pay = 3, + Finsh = 8, + Cacel = 16, + Refunding = 32 + } + [Fact] + public void SetEnum() + { + var fsql = g.mysql; + //#184 + fsql.Delete(Guid.Parse("5e83a910-672f-847c-00c1-316b71d153fb")).ExecuteAffrows(); + var item = new tenumcls { id = Guid.Parse("5e83a910-672f-847c-00c1-316b71d153fb"), status = tenum.Finsh }; + Assert.Equal("INSERT INTO `tenumcls`(`id`, `status`) VALUES('5e83a910-672f-847c-00c1-316b71d153fb', 'Finsh')", + fsql.Insert().NoneParameter().AppendData(item).ToSql()); + Assert.Equal(1, fsql.Insert().NoneParameter().AppendData(item).ExecuteAffrows()); + var item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = case when `id` = '5e83a910-672f-847c-00c1-316b71d153fb' then 'Pay' else 'Refunding' end +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Finsh' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status == tenum.Finsh).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status == tenum.Finsh).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Pay' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status == tenum.Pay).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status == tenum.Pay).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Finsh' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status, tenum.Finsh).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status, tenum.Finsh).ExecuteAffrows()); + item2 = fsql.Select().Where(a => a.id == item.id).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Finsh, item2.status); + + Assert.Equal(@"UPDATE `tenumcls` SET `status` = 'Pay' +WHERE (`id` = '5e83a910-672f-847c-00c1-316b71d153fb')", + fsql.Update(item).NoneParameter().Set(a => a.status, tenum.Pay).ToSql()); + Assert.Equal(1, fsql.Update(item).NoneParameter().Set(a => a.status, tenum.Pay).ExecuteAffrows()); + + Assert.Equal(@"SELECT a.`id`, a.`status` +FROM `tenumcls` a +WHERE (a.`id` = '5e83a910-672f-847c-00c1-316b71d153fb' AND a.`status` = case when a.`id` = '5e83a910-672f-847c-00c1-316b71d153fb' then 'Pay' else 'Refunding' end) +limit 0,1", fsql.Select().Where(a => a.id == item.id && a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).Limit(1).ToSql()); + item2 = fsql.Select().Where(a => a.id == item.id && a.status == (a.id == item.id ? tenum.Pay : tenum.Refunding)).First(); + Assert.Equal(item.id, item2.id); + Assert.Equal(tenum.Pay, item2.status); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + ?", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET clicks = clicks + ? WHERE (`Id` = 1)", sql); + } + [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = 1, `Title` = 'xxx' WHERE (`Id` = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET `Clicks` = 1, `Title` = 'xxx' WHERE (`Id` = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` = 1)", sql); + + sql = update.Where("id = ?", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (id = ?)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `tb_topic` SET title='newtitle' WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.mysql.Update().NoneParameter().Where(a => a.id == 0 && a.type == TestEnumUpdateTbType.str1) + .Set(a => a.type, TestEnumUpdateTbType.sum211).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE `TestEnumUpdateTb` SET `type` = 'sum211' WHERE (`id` = 0 AND `type` = 'str1')", sql); + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var time = DateTime.Now; + var items222 = g.mysql.Select().Where(a => a.CreateTime > time).Limit(10).ToList(); + + update.SetSource(items.First()).NoneParameter().ExecuteAffrows(); + update.SetSource(items).NoneParameter().ExecuteAffrows(); + } + [Fact] + public void ExecuteUpdated() + { + + } + + [Fact] + public void AsTable() + { + Assert.Null(g.mysql.Update().ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test' \r\nWHERE (`Id` IN (1,2))", g.mysql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` IN (1,2))", g.mysql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE `tb_topicAsTable` SET title='test1' \r\nWHERE (`Id` = 1)", g.mysql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/OnDuplicateKeyUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/OnDuplicateKeyUpdateTest.cs new file mode 100644 index 00000000..bc1dc8b1 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/Curd/OnDuplicateKeyUpdateTest.cs @@ -0,0 +1,195 @@ +using FreeSql.DataAnnotations; +using FreeSql.Custom.MySql; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.MySql +{ + public class OnDuplicateKeyUpdateTest + { + class TestOnDuplicateKeyUpdateInfo + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string title { get; set; } + public DateTime? time { get; set; } + } + + [Fact] + public void ExecuteAffrows() + { + g.mysql.Delete(new[] { 100, 101, 102 }).ExecuteAffrows(); + var odku1 = new CustomMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = VALUES(`time`)", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new CustomMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 101, title = "title-101", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 102, title = "title-102", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(100, 'title-100', '2000-01-01 00:00:00.000'), (101, 'title-101', '2000-01-01 00:00:00.000'), (102, 'title-102', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = VALUES(`time`)", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void IgnoreColumns() + { + g.mysql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + var odku1 = new CustomMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new CustomMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = CASE `id` +WHEN 200 THEN '2000-01-01 00:00:00.000' +WHEN 201 THEN '2000-01-01 00:00:00.000' +WHEN 202 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); + odku2.ExecuteAffrows(); + + + g.mysql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + odku1 = new CustomMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()).IgnoreColumns(a => a.title); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200') +ON DUPLICATE KEY UPDATE +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = new CustomMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()).IgnoreColumns(a => a.title); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON DUPLICATE KEY UPDATE +`time` = CASE `id` +WHEN 200 THEN '2000-01-01 00:00:00.000' +WHEN 201 THEN '2000-01-01 00:00:00.000' +WHEN 202 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void UpdateColumns() + { + g.mysql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + var odku1 = new CustomMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new CustomMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON DUPLICATE KEY UPDATE +`title` = VALUES(`title`), +`time` = CASE `id` +WHEN 300 THEN '2000-01-01 00:00:00.000' +WHEN 301 THEN '2000-01-01 00:00:00.000' +WHEN 302 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); + odku2.ExecuteAffrows(); + + + g.mysql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + odku1 = new CustomMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()).UpdateColumns(a => a.time); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300') +ON DUPLICATE KEY UPDATE +`time` = '2000-01-01 00:00:00.000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = new CustomMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()).UpdateColumns(a => a.time); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`) VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON DUPLICATE KEY UPDATE +`time` = CASE `id` +WHEN 300 THEN '2000-01-01 00:00:00.000' +WHEN 301 THEN '2000-01-01 00:00:00.000' +WHEN 302 THEN '2000-01-01 00:00:00.000' END", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void Set() + { + g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); + var odku1 = new CustomMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().InsertIdentity()).Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new CustomMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().InsertIdentity()).Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000'", odku2.ToSql()); + odku2.ExecuteAffrows(); + + + var dt2020 = DateTime.Parse("2020-1-1"); + g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); + odku1 = new CustomMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().InsertIdentity()).Set(a => a.time == dt2020); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = new CustomMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().InsertIdentity()).Set(a => a.time == dt2020); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000'", odku2.ToSql()); + odku2.ExecuteAffrows(); + + + g.mysql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); + odku1 = new CustomMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().InsertIdentity()).Set(a => new { time = dt2020, title = a.title + "123" }); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = new CustomMySqlOnDuplicateKeyUpdate(g.mysql.Insert(new[] { + new TestOnDuplicateKeyUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, + new TestOnDuplicateKeyUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().InsertIdentity()).Set(a => new { time = dt2020, title = a.title + "123" }); + Assert.Equal(@"INSERT INTO `TestOnDuplicateKeyUpdateInfo`(`id`, `title`, `time`) VALUES(400, 'title-400', '2000-01-01 00:00:00.000'), (401, 'title-401', '2000-01-01 00:00:00.000'), (402, 'title-402', '2000-01-01 00:00:00.000') +ON DUPLICATE KEY UPDATE +`time` = '2020-01-01 00:00:00.000', `title` = concat(`title`, '123')", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..b61d7525 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/BoolNullableTest.cs @@ -0,0 +1,1722 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Custom.MySqlMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.mysql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/BoolTest.cs new file mode 100644 index 00000000..c903baeb --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/BoolTest.cs @@ -0,0 +1,1130 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Custom.MySqlMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.mysql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + + [Fact] + public void MygisPoint() + { + } + [Fact] + public void MygisLineString() + { + } + [Fact] + public void MygisPolygon() + { + } + [Fact] + public void MygisMultiPoint() + { + } + [Fact] + public void MygisMultiLineString() + { + } + [Fact] + public void MygisMultiPolygon() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..9e2ea044 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,62 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Custom.MySqlMapType +{ + public class DateTimeOffSetTest + { + class DateTimeOffSetTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime?))] + public DateTimeOffset? dtosnullable_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.mysql; + var item = new DateTimeOffSetTestMap { dtos_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt, find.dtosnullable_to_dt); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt, find.dtosnullable_to_dt); + + item.dtosnullable_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/EnumTest.cs new file mode 100644 index 00000000..d25a78b1 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/EnumTest.cs @@ -0,0 +1,261 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Custom.MySqlMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() + { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.mysql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/ToStringTest.cs new file mode 100644 index 00000000..c6298eef --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MapType/ToStringTest.cs @@ -0,0 +1,570 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Custom.MySqlMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.mysql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlAdo/MySqlAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlAdo/MySqlAdoTest.cs new file mode 100644 index 00000000..d3acac24 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlAdo/MySqlAdoTest.cs @@ -0,0 +1,71 @@ +using FreeSql.DataAnnotations; +using System; +using System.Data.Odbc; +using Xunit; + +namespace FreeSql.Tests.Custom.MySql +{ + public class MySqlAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.mysql.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() + { + var t2 = g.mysql.Ado.SlavePools.Count; + } + + [Fact] + public void ExecuteTest() + { + Assert.True(g.mysql.Ado.ExecuteConnectTest()); + } + [Fact] + public void ExecuteReader() + { + + } + [Fact] + public void ExecuteArray() + { + + } + [Fact] + public void ExecuteNonQuery() + { + + } + [Fact] + public void ExecuteScalar() + { + + } + + [Fact] + public void Query() + { + var t3 = g.mysql.Ado.Query("select * from song"); + + var t4 = g.mysql.Ado.Query<(int, string, string)>("select * from song"); + + var t5 = g.mysql.Ado.Query("select * from song"); + } + + [Fact] + public void QueryMultipline() + { + Assert.Throws(() => g.mysql.Ado.Query("select * from song; select * from song; select * from song")); + } + + class xxx + { + public int Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlAopTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlAopTest.cs new file mode 100644 index 00000000..fe8e9f4a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Custom.MySql +{ + public class MySqlAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var date = DateTime.Now.Date; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now.Date; + }; + g.mysql.Aop.AuditValue += audit; + + g.mysql.Insert(item).ExecuteAffrows(); + + g.mysql.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime, date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlCodeFirstTest.cs new file mode 100644 index 00000000..99788a25 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlCodeFirstTest.cs @@ -0,0 +1,577 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Custom.MySql +{ + public class MySqlCodeFirstTest + { + [Fact] + public void Test_0String() + { + var fsql = g.mysql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + + Assert.Equal(1, fsql.Insert(new test_0string01 { name = @"1.0000\0.0000\0.0000\0.0000\1.0000\0.0000" }).ExecuteAffrows()); + Assert.Equal(1, fsql.Insert(new test_0string01 { name = @"1.0000\0.0000\0.0000\0.0000\1.0000\0.0000" }).NoneParameter().ExecuteAffrows()); + + var list = fsql.Select().ToList(); + Assert.Equal(2, list.Count); + Assert.Equal(@"1.0000\0.0000\0.0000\0.0000\1.0000\0.0000", list[0].name); + Assert.Equal(@"1.0000\0.0000\0.0000\0.0000\1.0000\0.0000", list[1].name); + } + class test_0string01 + { + public Guid id { get; set; } + public string name { get; set; } + } + + [Fact] + public void EnumStartValue1() + { + var fsql = g.mysql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + + var repo = fsql.GetRepository(); + var item1 = repo.Insert(new TS_ESV1 { Status = TS_TSV1_Status.Status1 }); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status1, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status1, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status1, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status1, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status1' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status, TS_TSV1_Status.Status1).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status2' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status, TS_TSV1_Status.Status2).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status3' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status, TS_TSV1_Status.Status3).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status1' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status == TS_TSV1_Status.Status1).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status2' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status == TS_TSV1_Status.Status2).ToSql().Replace("\r\n", "")); + Assert.Equal($"UPDATE `TS_ESV1` SET `Status` = 'Status3' WHERE (`Id` = '{item1.Id}')", fsql.Update().Where(a => a.Id == item1.Id).NoneParameter().Set(a => a.Status == TS_TSV1_Status.Status3).ToSql().Replace("\r\n", "")); + + item1.Status = TS_TSV1_Status.Status1; + repo.Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status1, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status1, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status1, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status1, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + item1.Status = TS_TSV1_Status.Status2; + repo.Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status2, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status2, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status2, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status2, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + item1.Status = TS_TSV1_Status.Status3; + repo.Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status3, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status3, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status3, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status3, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + item1.Status = TS_TSV1_Status.Status3; + fsql.GetRepository().Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status3, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status3, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status3, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status3, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + + item1.Status = TS_TSV1_Status.Status2; + fsql.GetRepository().Update(item1); + Assert.True(fsql.Select().Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status2, fsql.Select().Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status2, fsql.Select().Where(a => a.Id == item1.Id).First(a => a.Status)); + Assert.True(repo.Select.Where(a => a.Id == item1.Id).Any()); + Assert.Equal(TS_TSV1_Status.Status2, repo.Select.Where(a => a.Id == item1.Id).First().Status); + Assert.Equal(TS_TSV1_Status.Status2, repo.Select.Where(a => a.Id == item1.Id).First(a => a.Status)); + } + public class TS_ESV1 + { + public Guid Id { get; set; } + public TS_TSV1_Status Status { get; set; } + } + public enum TS_TSV1_Status + { + Status1 = 1, + Status2 = 3, + Status3 = 5 + } + + [Fact] + public void StringLength() + { + var dll = g.mysql.CodeFirst.GetComparisonDDLStatements(); + g.mysql.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } + } + + [Fact] + public void 表名中有点() + { + var item = new tbdot01 { name = "insert" }; + g.mysql.Insert(item).ExecuteAffrows(); + + var find = g.mysql.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal("insert", find.name); + + Assert.Equal(1, g.mysql.Update().Set(a => a.name == "update").Where(a => a.id == item.id).ExecuteAffrows()); + find = g.mysql.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal("update", find.name); + + Assert.Equal(1, g.mysql.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + find = g.mysql.Select().Where(a => a.id == item.id).First(); + Assert.Null(find); + } + [Table(Name = "`sys.tbdot01`")] + class tbdot01 + { + public Guid id { get; set; } + public string name { get; set; } + } + + [Fact] + public void 中文表_字段() + { + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements<测试中文表2>(); + g.mysql.CodeFirst.SyncStructure<测试中文表2>(); + + var item = new 测试中文表2 + { + 标题 = "测试标题", + 创建时间 = DateTime.Now + }; + Assert.Equal(1, g.mysql.Insert<测试中文表2>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.编号); + var item2 = g.mysql.Select<测试中文表2>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新"; + Assert.Equal(1, g.mysql.Update<测试中文表2>().SetSource(item).ExecuteAffrows()); + item2 = g.mysql.Select<测试中文表2>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新_repo"; + var repo = g.mysql.GetRepository<测试中文表2>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.mysql.Select<测试中文表2>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.mysql.Select<测试中文表2>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + } + class 测试中文表2 + { + [Column(IsPrimary = true)] + public Guid 编号 { get; set; } + + public string 标题 { get; set; } + + public DateTime 创建时间 { get; set; } + } + + [Fact] + public void AddUniques() + { + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + g.mysql.CodeFirst.SyncStructure(); + g.mysql.CodeFirst.SyncStructure(typeof(AddUniquesInfo), "AddUniquesInfo1"); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + class AddUniquesInfo + { + public Guid id { get; set; } + public string phone { get; set; } + + public string group { get; set; } + public int index { get; set; } + public string index22 { get; set; } + } + + [Fact] + public void AddField() + { + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + + 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 string name { get; set; } + + [Column(DbType = "varchar(200) not null", OldName = "title")] + public string title222 { get; set; } = "10"; + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() + { + + var sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + Assert.True(string.IsNullOrEmpty(sql)); //测试运行两次后 + sql = g.mysql.CodeFirst.GetComparisonDDLStatements(); + } + + IInsert insert => g.mysql.Insert(); + ISelect select => g.mysql.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + testFieldBool = true, + testFieldBoolNullable = true, + testFieldByte = 255, + testFieldByteNullable = 127, + testFieldBytes = Encoding.UTF8.GetBytes("我是中国人"), + testFieldDateTime = DateTime.Now, + testFieldDateTimeNullable = DateTime.Now.AddHours(-1), + testFieldDecimal = 99.99M, + testFieldDecimalNullable = 99.98M, + testFieldDouble = 999.99, + testFieldDoubleNullable = 999.98, + testFieldEnum1 = TableAllTypeEnumType1.e5, + testFieldEnum1Nullable = TableAllTypeEnumType1.e3, + testFieldEnum2 = TableAllTypeEnumType2.f2, + testFieldEnum2Nullable = TableAllTypeEnumType2.f3, + testFieldFloat = 19.99F, + testFieldFloatNullable = 19.98F, + testFieldGuid = Guid.NewGuid(), + testFieldGuidNullable = Guid.NewGuid(), + testFieldInt = int.MaxValue, + testFieldIntNullable = int.MinValue, + testFieldSByte = 100, + testFieldSByteNullable = 99, + testFieldShort = short.MaxValue, + testFieldShortNullable = short.MinValue, + testFieldString = "我是中国人string'\\?!@#$%^&*()_+{}}{~?><<>", + testFieldChar = 'X', + testFieldTimeSpan = TimeSpan.FromSeconds(999), + testFieldTimeSpanNullable = TimeSpan.FromSeconds(60), + testFieldUInt = uint.MaxValue, + testFieldUIntNullable = uint.MinValue, + testFieldULong = ulong.MaxValue, + testFieldULongNullable = ulong.MinValue, + testFieldUShort = ushort.MaxValue, + testFieldUShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteIdentity(); + + var enumConvInt = select.Where(a => a.Id == (int)TableAllTypeEnumType1.e1).ToSql(); + + item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); + + item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); + newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); + + var items = select.ToList(); + var itemstb = select.ToDataTable(); + } + + + [JsonObject(MemberSerialization.OptIn), Table(Name = "tb_alltype")] + public partial class Tb_alltype + { + + [JsonProperty, Column(Name = "Id", DbType = "int(11)", IsPrimary = true, IsIdentity = true)] + public int Id { get; set; } + + + [JsonProperty, Column(Name = "testFieldBool", DbType = "bit(1)")] + public bool TestFieldBool { get; set; } + + + [JsonProperty, Column(Name = "testFieldBoolNullable", DbType = "bit(1)", IsNullable = true)] + public bool? TestFieldBoolNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldByte", DbType = "tinyint(3) unsigned")] + public byte TestFieldByte { get; set; } + + + [JsonProperty, Column(Name = "testFieldByteNullable", DbType = "tinyint(3) unsigned", IsNullable = true)] + public byte? TestFieldByteNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldBytes", DbType = "varbinary(255)", IsNullable = true)] + public byte[] TestFieldBytes { get; set; } + + + [JsonProperty, Column(Name = "testFieldDateTime", DbType = "datetime")] + public DateTime TestFieldDateTime { get; set; } + + + [JsonProperty, Column(Name = "testFieldDateTimeNullable", DbType = "datetime", IsNullable = true)] + public DateTime? TestFieldDateTimeNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldDecimal", DbType = "decimal(10,2)")] + public decimal TestFieldDecimal { get; set; } + + + [JsonProperty, Column(Name = "testFieldDecimalNullable", DbType = "decimal(10,2)", IsNullable = true)] + public decimal? TestFieldDecimalNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldDouble", DbType = "double")] + public double TestFieldDouble { get; set; } + + + [JsonProperty, Column(Name = "testFieldDoubleNullable", DbType = "double", IsNullable = true)] + public double? TestFieldDoubleNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum1", DbType = "enum('E1','E2','E3','E5')")] + public Tb_alltypeTESTFIELDENUM1 TestFieldEnum1 { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum1Nullable", DbType = "enum('E1','E2','E3','E5')", IsNullable = true)] + public Tb_alltypeTESTFIELDENUM1NULLABLE? TestFieldEnum1Nullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum2", DbType = "set('F1','F2','F3')")] + public Tb_alltypeTESTFIELDENUM2 TestFieldEnum2 { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum2Nullable", DbType = "set('F1','F2','F3')", IsNullable = true)] + public Tb_alltypeTESTFIELDENUM2NULLABLE? TestFieldEnum2Nullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldFloat", DbType = "float")] + public float TestFieldFloat { get; set; } + + + [JsonProperty, Column(Name = "testFieldFloatNullable", DbType = "float", IsNullable = true)] + public float? TestFieldFloatNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldGuid", DbType = "char(36)")] + public Guid TestFieldGuid { get; set; } + + + [JsonProperty, Column(Name = "testFieldGuidNullable", DbType = "char(36)", IsNullable = true)] + public Guid? TestFieldGuidNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldInt", DbType = "int(11)")] + public int TestFieldInt { get; set; } + + + [JsonProperty, Column(Name = "testFieldIntNullable", DbType = "int(11)", IsNullable = true)] + public int? TestFieldIntNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldLong", DbType = "bigint(20)")] + public long TestFieldLong { get; set; } + + + [JsonProperty, Column(Name = "testFieldSByte", DbType = "tinyint(3)")] + public sbyte TestFieldSByte { get; set; } + + + [JsonProperty, Column(Name = "testFieldSByteNullable", DbType = "tinyint(3)", IsNullable = true)] + public sbyte? TestFieldSByteNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldShort", DbType = "smallint(6)")] + public short TestFieldShort { get; set; } + + + [JsonProperty, Column(Name = "testFieldShortNullable", DbType = "smallint(6)", IsNullable = true)] + public short? TestFieldShortNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldString", DbType = "varchar(255)", IsNullable = true)] + public string TestFieldString { get; set; } + + + [JsonProperty, Column(Name = "testFieldChar", DbType = "char(1)", IsNullable = true)] + public char testFieldChar { get; set; } + + + [JsonProperty, Column(Name = "testFieldTimeSpan", DbType = "time")] + public TimeSpan TestFieldTimeSpan { get; set; } + + + [JsonProperty, Column(Name = "testFieldTimeSpanNullable", DbType = "time", IsNullable = true)] + public TimeSpan? TestFieldTimeSpanNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldUInt", DbType = "int(10) unsigned")] + public uint TestFieldUInt { get; set; } + + + [JsonProperty, Column(Name = "testFieldUIntNullable", DbType = "int(10) unsigned", IsNullable = true)] + public uint? TestFieldUIntNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldULong", DbType = "bigint(20) unsigned")] + public ulong TestFieldULong { get; set; } + + + [JsonProperty, Column(Name = "testFieldULongNullable", DbType = "bigint(20) unsigned", IsNullable = true)] + public ulong? TestFieldULongNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldUShort", DbType = "smallint(5) unsigned")] + public ushort TestFieldUShort { get; set; } + + + [JsonProperty, Column(Name = "testFieldUShortNullable", DbType = "smallint(5) unsigned", IsNullable = true)] + public ushort? TestFieldUShortNullable { get; set; } + + + [JsonProperty, Column(Name = "testFielLongNullable", DbType = "bigint(20)", IsNullable = true)] + public long? TestFielLongNullable { get; set; } + + internal static IFreeSql mysql => null; + public static FreeSql.ISelect Select => mysql.Select(); + + public static long Delete(int Id) + { + var affrows = mysql.Delete().Where(a => a.Id == Id).ExecuteAffrows(); + return affrows; + } + + /// + /// 保存或添加,如果主键有值则尝试 Update,如果影响的行为 0 则尝试 Insert + /// + public void Save() + { + if (this.Id != default(int)) + { + var affrows = mysql.Update().Where(a => a.Id == Id).ExecuteAffrows(); + if (affrows > 0) return; + } + this.Id = (int)mysql.Insert().AppendData(this).ExecuteIdentity(); + } + + } + + public enum Tb_alltypeTESTFIELDENUM1 + { + E1 = 1, E2, E3, E5 + } + public enum Tb_alltypeTESTFIELDENUM1NULLABLE + { + E1 = 1, E2, E3, E5 + } + [Flags] + public enum Tb_alltypeTESTFIELDENUM2 : long + { + F1 = 1, F2 = 2, F3 = 4 + } + [Flags] + public enum Tb_alltypeTESTFIELDENUM2NULLABLE : long + { + F1 = 1, F2 = 2, F3 = 4 + } + + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + 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 byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public char testFieldChar { 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 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/FreeSql.Tests.Provider.Custom/MySql/MySqlDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlDbFirstTest.cs new file mode 100644 index 00000000..bb6b122b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlDbFirstTest.cs @@ -0,0 +1,64 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Custom.MySql +{ + public class MySqlDbFirstTest + { + [Fact] + public void GetDatabases() + { + var t1 = g.mysql.DbFirst.GetDatabases(); + } + + [Fact] + public void GetTablesByDatabase() + { + var t2 = g.mysql.DbFirst.GetTablesByDatabase(g.mysql.DbFirst.GetDatabases()[0]); + Assert.True(t2.Count > 0); + } + + [Fact] + public void GetTableByName() + { + var fsql = g.mysql; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("cccddd_odbc.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); + } + + [Fact] + public void ExistsTable() + { + var fsql = g.mysql; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("cccddd_odbc.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("cccddd_odbc.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("cccddd_odbc.test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("Test_existstb01", false)); + Assert.True(fsql.DbFirst.ExistsTable("cccddd_odbc.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("cccddd_odbc.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("cccddd_odbc.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "cccddd_odbc.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("cccddd_odbc.test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("cccddd_odbc.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table cccddd_odbc.test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/ConvertTest.cs new file mode 100644 index 00000000..f8566951 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/ConvertTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.MySqlExpression +{ + public class ConvertTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() + { + var data = new List(); + data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/DateTimeTest.cs new file mode 100644 index 00000000..dde93a54 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/DateTimeTest.cs @@ -0,0 +1,720 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.MySqlExpression +{ + public class DateTimeTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInfo23123")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + g.mysql.Insert(new Topic()).ExecuteAffrows(); + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t").Replace("", "AM").Replace("", "PM").Replace("", "A").Replace("", "P"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t"))); + } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, now(), a.`CreateTime`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, now(), a__Type.`Time`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, now(), a__Type__Parent.`Time2`)) / 1000000) > 0); + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_sub(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_sub(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_sub(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`) + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, now(), a.`CreateTime`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, now(), a__Type.`Time`)) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, now(), a__Type__Parent.`Time2`)) / 1000000) > 0); + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_sub(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_sub(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_sub(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > a.`CreateTime`) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/MathTest.cs new file mode 100644 index 00000000..3c18740a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/MathTest.cs @@ -0,0 +1,156 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.MySqlExpression +{ + public class MathTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + var data = new List(); + data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/OtherTest.cs new file mode 100644 index 00000000..b34e8972 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/OtherTest.cs @@ -0,0 +1,166 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Data.Odbc; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.MySqlExpression +{ + public class OtherTest + { + + ISelect select => g.mysql.Select(); + + public OtherTest() + { + + } + + [Fact] + public void Div() + { + var t1 = select.Where(a => a.testFieldInt / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.testFieldLong / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.testFieldShort / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.testFieldInt / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.testFieldLong / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.testFieldShort / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.testFieldDouble / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.testFieldDecimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.testFieldFloat / 3 > 3).Limit(10).ToList(); + } + + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.testFieldBool == true).ToList(); + var t2 = select.Where(a => a.testFieldBool != true).ToList(); + var t3 = select.Where(a => a.testFieldBool == false).ToList(); + var t4 = select.Where(a => !a.testFieldBool).ToList(); + var t5 = select.Where(a => a.testFieldBool).ToList(); + var t51 = select.WhereCascade(a => a.testFieldBool).Limit(10).ToList(); + + var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); + var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); + var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); + var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); + var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.testFieldBool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.testFieldBool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.testFieldBool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.testFieldBool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.testFieldBool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.testFieldBool == true && a.Id > 0 && a.testFieldBool == true).ToList(); + var t22222 = select.Where(a => a.testFieldBool != true && a.Id > 0 && a.testFieldBool != true).ToList(); + var t33333 = select.Where(a => a.testFieldBool == false && a.Id > 0 && a.testFieldBool == false).ToList(); + var t44444 = select.Where(a => !a.testFieldBool && a.Id > 0 && !a.testFieldBool).ToList(); + var t55555 = select.Where(a => a.testFieldBool && a.Id > 0 && a.testFieldBool).ToList(); + + var t111111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0 && a.testFieldBoolNullable == true).ToList(); + var t222222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0 && a.testFieldBoolNullable != true).ToList(); + var t333333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0 && a.testFieldBoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0 && !a.testFieldBoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0 && a.testFieldBoolNullable.Value).ToList(); + } + + [Fact] + public void Array() + { + int[] nullarr = null; + Assert.Throws(() => { select.Where(a => nullarr.Contains(a.testFieldInt)).ToList(); }); + Assert.Throws(() => { select.Where(a => new int[0].Contains(a.testFieldInt)).ToList(); }); + + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.testFieldInt)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.testFieldInt) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.testFieldInt)).ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + 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 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 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/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/StringTest.cs new file mode 100644 index 00000000..11a11880 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/StringTest.cs @@ -0,0 +1,831 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.MySqlExpression +{ + public class StringTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + public bool IsDeleted { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.mysql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); + } + + [Fact] + public void StringJoin() + { + var fsql = g.mysql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + + [Fact] + public void Format() + { + var item = g.mysql.GetRepository().Insert(new Topic { Clicks = 101, Title = "我是中国人101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT concat('x',ifnull((a.`Id` + 1), ''),'z-',ifnull(date_format(a.`CreateTime`,'%Y%m'), ''),'',ifnull(a.`Title`, ''),'') as1, concat('',ifnull((a.`Id` + 1), ''),'x',ifnull((a.`Id` + 1), ''),'z-',ifnull(date_format(a.`CreateTime`,'%Y%m'), ''),'',ifnull(a.`Title`, ''),'') as2 +FROM `tb_topic` a +WHERE (a.`Id` = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + + [Fact] + public void Format4() + { + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var item = g.mysql.GetRepository().Insert(new Topic { Clicks = 101, Title = "我是中国人101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT concat('x',ifnull((a.`Id` + 1), ''),'z-',ifnull(date_format(a.`CreateTime`,'%Y%m'), ''),'',ifnull(a.`Title`, ''),'',ifnull(a.`Title`, ''),'') as1, concat('',ifnull((a.`Id` + 1), ''),'x',ifnull((a.`Id` + 1), ''),'z-',ifnull(date_format(a.`CreateTime`,'%Y%m'), ''),'',ifnull(a.`Title`, ''),'',ifnull(a.`Title`, ''),'') as2 +FROM `tb_topic` a +WHERE (a.`Id` = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + + + list.Add(select.Where(a => a.Title.Contains("%")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + "%")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1 + "%")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name + "%")).ToList()); + + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa" + "%")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + "%")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1 + "%")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name + "%")).ToList()); + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/TimeSpanTest.cs new file mode 100644 index 00000000..3a46c4e3 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/MySql/MySqlExpression/TimeSpanTest.cs @@ -0,0 +1,293 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.MySqlExpression +{ + public class TimeSpanTest + { + + ISelect select => g.mysql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } + + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleDeleteTest.cs new file mode 100644 index 00000000..11c879e7 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleDeleteTest.cs @@ -0,0 +1,106 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.Oracle +{ + public class OracleDeleteTest + { + + IDelete delete => g.oracle.Delete(); //�������� + + [Table(Name = "tb_topic22211")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.oracle.Delete().ToSql()); + var sql = g.oracle.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2))", sql); + + sql = g.oracle.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = g.oracle.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2))", sql); + + sql = g.oracle.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = g.oracle.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM \"MULTIPKTOPIC\" WHERE (\"ID1\" = 1 AND \"ID2\" = 10 OR \"ID1\" = 2 AND \"ID2\" = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + sql = delete.Where("id = :id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (id = :id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"TB_TOPIC22211\" WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + + var id = g.oracle.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { + + //var item = g.oracle.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); + //Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.oracle.Delete().ToSql()); + var sql = g.oracle.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); + + sql = g.oracle.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); + + sql = g.oracle.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" IN (1,2))", sql); + + sql = g.oracle.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"TOPICASTABLE\" WHERE (\"ID\" = 1)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..160ec7d8 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,425 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.Oracle +{ + public class OracleInsertOrUpdateIfExistsDoNothingTest + { + IFreeSql fsql => g.oracle; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ""ID"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.""ID"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ""ID"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.""ID"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 2 as ""ID"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.""ID"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ""ID"" FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.""ID"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB01"" t1 +USING (SELECT 1 as ""ID"" FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.""ID"")", sql); + iou.ExecuteAffrows(); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ""ID"", '01' as ""NAME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ""ID"", '011' as ""NAME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 2 as ""ID"", '02' as ""NAME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ""ID"", '01' as ""NAME"" FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB02"" t1 +USING (SELECT 1 as ""ID"", '001' as ""NAME"" FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ""ID"", '01' as ""NAME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ""ID"", '011' as ""NAME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 2 as ""ID"", '02' as ""NAME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ""ID"", '01' as ""NAME"" FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ""ID"", '001' as ""NAME"" FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('01')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('011')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOUDB022""(""NAME"") VALUES('02')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDB022""(""NAME"") VALUES('01') +INTO ""TBIOUDB022""(""NAME"") VALUES('02') +INTO ""TBIOUDB022""(""NAME"") VALUES('03') +INTO ""TBIOUDB022""(""NAME"") VALUES('04') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOUDB022""(""NAME"") VALUES('001') +INTO ""TBIOUDB022""(""NAME"") VALUES('002') +INTO ""TBIOUDB022""(""NAME"") VALUES('003') +INTO ""TBIOUDB022""(""NAME"") VALUES('004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB022"" t1 +USING (SELECT 1 as ""ID"", '100001' as ""NAME"" FROM dual +UNION ALL + SELECT 2, '100002' FROM dual +UNION ALL + SELECT 3, '100003' FROM dual +UNION ALL + SELECT 4, '100004' FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"") + +; + +INSERT ALL +INTO ""TBIOUDB022""(""NAME"") VALUES('00001') +INTO ""TBIOUDB022""(""NAME"") VALUES('00002') +INTO ""TBIOUDB022""(""NAME"") VALUES('00003') +INTO ""TBIOUDB022""(""NAME"") VALUES('00004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ""ID1"", '01' as ""ID2"", '01' as ""NAME"" FROM dual ) t2 ON (t1.""ID1"" = t2.""ID1"" AND t1.""ID2"" = t2.""ID2"") +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.""ID1"", t2.""ID2"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ""ID1"", '01' as ""ID2"", '011' as ""NAME"" FROM dual ) t2 ON (t1.""ID1"" = t2.""ID1"" AND t1.""ID2"" = t2.""ID2"") +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.""ID1"", t2.""ID2"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 2 as ""ID1"", '02' as ""ID2"", '02' as ""NAME"" FROM dual ) t2 ON (t1.""ID1"" = t2.""ID1"" AND t1.""ID2"" = t2.""ID2"") +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.""ID1"", t2.""ID2"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ""ID1"", '01' as ""ID2"", '01' as ""NAME"" FROM dual +UNION ALL + SELECT 2, '02', '02' FROM dual +UNION ALL + SELECT 3, '03', '03' FROM dual +UNION ALL + SELECT 4, '04', '04' FROM dual ) t2 ON (t1.""ID1"" = t2.""ID1"" AND t1.""ID2"" = t2.""ID2"") +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.""ID1"", t2.""ID2"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB03"" t1 +USING (SELECT 1 as ""ID1"", '01' as ""ID2"", '001' as ""NAME"" FROM dual +UNION ALL + SELECT 2, '02', '002' FROM dual +UNION ALL + SELECT 3, '03', '003' FROM dual +UNION ALL + SELECT 4, '04', '004' FROM dual ) t2 ON (t1.""ID1"" = t2.""ID1"" AND t1.""ID2"" = t2.""ID2"") +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.""ID1"", t2.""ID2"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ""ID"", '01' as ""NAME"", 0 as ""VERSION"", systimestamp as ""CREATETIME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.""ID"", t2.""NAME"", t2.""VERSION"", t2.""CREATETIME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ""ID"", '011' as ""NAME"", 0 as ""VERSION"", systimestamp as ""CREATETIME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.""ID"", t2.""NAME"", t2.""VERSION"", t2.""CREATETIME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 2 as ""ID"", '02' as ""NAME"", 0 as ""VERSION"", systimestamp as ""CREATETIME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.""ID"", t2.""NAME"", t2.""VERSION"", t2.""CREATETIME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ""ID"", '01' as ""NAME"", 0 as ""VERSION"", systimestamp as ""CREATETIME"" FROM dual +UNION ALL + SELECT 2, '02', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '03', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '04', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.""ID"", t2.""NAME"", t2.""VERSION"", t2.""CREATETIME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOUDB04"" t1 +USING (SELECT 1 as ""ID"", '001' as ""NAME"", 0 as ""VERSION"", systimestamp as ""CREATETIME"" FROM dual +UNION ALL + SELECT 2, '002', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '003', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '004', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.""ID"", t2.""NAME"", t2.""VERSION"", t2.""CREATETIME"")", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleInsertOrUpdateTest.cs new file mode 100644 index 00000000..47974292 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleInsertOrUpdateTest.cs @@ -0,0 +1,467 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.Oracle +{ + public class OracleInsertOrUpdateTest + { + IFreeSql fsql => g.oracle; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ""ID"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.""ID"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ""ID"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.""ID"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 2 as ""ID"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.""ID"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ""ID"" FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.""ID"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU01"" t1 +USING (SELECT 1 as ""ID"" FROM dual +UNION ALL + SELECT 2 FROM dual +UNION ALL + SELECT 3 FROM dual +UNION ALL + SELECT 4 FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN NOT MATCHED THEN + insert (""ID"") + values (t2.""ID"")", sql); + iou.ExecuteAffrows(); + } + class tbiou01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ""ID"", '01' as ""NAME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"" +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ""ID"", '011' as ""NAME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"" +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 2 as ""ID"", '02' as ""NAME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"" +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ""ID"", '01' as ""NAME"" FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"" +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU02"" t1 +USING (SELECT 1 as ""ID"", '001' as ""NAME"" FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"" +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ""ID"", '01' as ""NAME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"" +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ""ID"", '011' as ""NAME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"" +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 2 as ""ID"", '02' as ""NAME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"" +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ""ID"", '01' as ""NAME"" FROM dual +UNION ALL + SELECT 2, '02' FROM dual +UNION ALL + SELECT 3, '03' FROM dual +UNION ALL + SELECT 4, '04' FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"" +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ""ID"", '001' as ""NAME"" FROM dual +UNION ALL + SELECT 2, '002' FROM dual +UNION ALL + SELECT 3, '003' FROM dual +UNION ALL + SELECT 4, '004' FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"" +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('01')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('011')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""TBIOU022""(""NAME"") VALUES('02')", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOU022""(""NAME"") VALUES('01') +INTO ""TBIOU022""(""NAME"") VALUES('02') +INTO ""TBIOU022""(""NAME"") VALUES('03') +INTO ""TBIOU022""(""NAME"") VALUES('04') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TBIOU022""(""NAME"") VALUES('001') +INTO ""TBIOU022""(""NAME"") VALUES('002') +INTO ""TBIOU022""(""NAME"") VALUES('003') +INTO ""TBIOU022""(""NAME"") VALUES('004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU022"" t1 +USING (SELECT 1 as ""ID"", '100001' as ""NAME"" FROM dual +UNION ALL + SELECT 2, '100002' FROM dual +UNION ALL + SELECT 3, '100003' FROM dual +UNION ALL + SELECT 4, '100004' FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"" +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"") + values (t2.""ID"", t2.""NAME"") + +; + +INSERT ALL +INTO ""TBIOU022""(""NAME"") VALUES('00001') +INTO ""TBIOU022""(""NAME"") VALUES('00002') +INTO ""TBIOU022""(""NAME"") VALUES('00003') +INTO ""TBIOU022""(""NAME"") VALUES('00004') + SELECT 1 FROM DUAL", sql); + iou.ExecuteAffrows(); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + //Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ""ID1"", '01' as ""ID2"", '01' as ""NAME"" FROM dual ) t2 ON (t1.""ID1"" = t2.""ID1"" AND t1.""ID2"" = t2.""ID2"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"" +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.""ID1"", t2.""ID2"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ""ID1"", '01' as ""ID2"", '011' as ""NAME"" FROM dual ) t2 ON (t1.""ID1"" = t2.""ID1"" AND t1.""ID2"" = t2.""ID2"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"" +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.""ID1"", t2.""ID2"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 2 as ""ID1"", '02' as ""ID2"", '02' as ""NAME"" FROM dual ) t2 ON (t1.""ID1"" = t2.""ID1"" AND t1.""ID2"" = t2.""ID2"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"" +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.""ID1"", t2.""ID2"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ""ID1"", '01' as ""ID2"", '01' as ""NAME"" FROM dual +UNION ALL + SELECT 2, '02', '02' FROM dual +UNION ALL + SELECT 3, '03', '03' FROM dual +UNION ALL + SELECT 4, '04', '04' FROM dual ) t2 ON (t1.""ID1"" = t2.""ID1"" AND t1.""ID2"" = t2.""ID2"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"" +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.""ID1"", t2.""ID2"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU03"" t1 +USING (SELECT 1 as ""ID1"", '01' as ""ID2"", '001' as ""NAME"" FROM dual +UNION ALL + SELECT 2, '02', '002' FROM dual +UNION ALL + SELECT 3, '03', '003' FROM dual +UNION ALL + SELECT 4, '04', '004' FROM dual ) t2 ON (t1.""ID1"" = t2.""ID1"" AND t1.""ID2"" = t2.""ID2"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"" +WHEN NOT MATCHED THEN + insert (""ID1"", ""ID2"", ""NAME"") + values (t2.""ID1"", t2.""ID2"", t2.""NAME"")", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ""ID"", '01' as ""NAME"", 0 as ""VERSION"", systimestamp as ""CREATETIME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"", ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.""ID"", t2.""NAME"", t2.""VERSION"", t2.""CREATETIME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ""ID"", '011' as ""NAME"", 0 as ""VERSION"", systimestamp as ""CREATETIME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"", ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.""ID"", t2.""NAME"", t2.""VERSION"", t2.""CREATETIME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 2 as ""ID"", '02' as ""NAME"", 0 as ""VERSION"", systimestamp as ""CREATETIME"" FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"", ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.""ID"", t2.""NAME"", t2.""VERSION"", t2.""CREATETIME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ""ID"", '01' as ""NAME"", 0 as ""VERSION"", systimestamp as ""CREATETIME"" FROM dual +UNION ALL + SELECT 2, '02', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '03', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '04', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"", ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.""ID"", t2.""NAME"", t2.""VERSION"", t2.""CREATETIME"")", sql); + iou.ExecuteAffrows(); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO ""TBIOU04"" t1 +USING (SELECT 1 as ""ID"", '001' as ""NAME"", 0 as ""VERSION"", systimestamp as ""CREATETIME"" FROM dual +UNION ALL + SELECT 2, '002', 0, systimestamp FROM dual +UNION ALL + SELECT 3, '003', 0, systimestamp FROM dual +UNION ALL + SELECT 4, '004', 0, systimestamp FROM dual ) t2 ON (t1.""ID"" = t2.""ID"") +WHEN MATCHED THEN + update set ""NAME"" = t2.""NAME"", ""VERSION"" = t1.""VERSION"" + 1 +WHEN NOT MATCHED THEN + insert (""ID"", ""NAME"", ""VERSION"", ""CREATETIME"") + values (t2.""ID"", t2.""NAME"", t2.""VERSION"", t2.""CREATETIME"")", sql); + iou.ExecuteAffrows(); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleInsertTest.cs new file mode 100644 index 00000000..51011b42 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleInsertTest.cs @@ -0,0 +1,278 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.Oracle +{ + public class OracleInsertTest + { + + IInsert insert => g.oracle.Insert(); //�������� + + [Table(Name = "tb_topic_insert")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Parse("2019-09-19 22:25:38.697071") }); + + var data = new List(); + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO \"TB_TOPIC_INSERT\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(0, 'newtitle0', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6'))", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(0, 'newtitle0', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(100, 'newtitle1', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(200, 'newtitle2', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(300, 'newtitle3', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(400, 'newtitle4', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(500, 'newtitle5', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(600, 'newtitle6', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(700, 'newtitle7', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(800, 'newtitle8', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(900, 'newtitle9', to_timestamp('2019-09-19 22:25:38.697071','YYYY-MM-DD HH24:MI:SS.FF6')) + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle0') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle1') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle2') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle3') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle4') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle5') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle6') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle7') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle8') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(0, 'newtitle0') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(100, 'newtitle1') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(200, 'newtitle2') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(300, 'newtitle3') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(400, 'newtitle4') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(500, 'newtitle5') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(600, 'newtitle6') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(700, 'newtitle7') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(800, 'newtitle8') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(900, 'newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + } + + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var data = new List(); + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle0') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle1') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle2') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle3') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle4') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle5') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle6') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle7') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle8') +INTO ""TB_TOPIC_INSERT""(""TITLE"") VALUES('newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(0, 'newtitle0') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(100, 'newtitle1') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(200, 'newtitle2') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(300, 'newtitle3') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(400, 'newtitle4') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(500, 'newtitle5') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(600, 'newtitle6') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(700, 'newtitle7') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(800, 'newtitle8') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(900, 'newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var data = new List(); + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(0, 'newtitle0') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(100, 'newtitle1') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(200, 'newtitle2') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(300, 'newtitle3') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(400, 'newtitle4') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(500, 'newtitle5') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(600, 'newtitle6') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(700, 'newtitle7') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(800, 'newtitle8') +INTO ""TB_TOPIC_INSERT""(""CLICKS"", ""TITLE"") VALUES(900, 'newtitle9') + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(0) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(100) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(200) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(300) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(400) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(500) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(600) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(700) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(800) +INTO ""TB_TOPIC_INSERT""(""CLICKS"") VALUES(900) + SELECT 1 FROM DUAL", sql); + data.Add(insert.AppendData(items.First()).ExecuteIdentity()); + + g.oracle.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.oracle.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.oracle.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicICs")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void ExecuteInserted() + { + //var items = new List(); + //for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + //var items2 = insert.AppendData(items).ExecuteInserted(); + } + + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"TOPIC_INSERTASTABLE\"(\"CLICKS\", \"TITLE\", \"CREATETIME\") VALUES(0, 'newTitle0', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6'))", sql); + + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(0, 'newTitle0', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(100, 'newTitle1', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(200, 'newTitle2', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(300, 'newTitle3', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(400, 'newTitle4', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(500, 'newTitle5', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(600, 'newTitle6', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(700, 'newTitle7', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(800, 'newTitle8', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"", ""CREATETIME"") VALUES(900, 'newTitle9', to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) + SELECT 1 FROM DUAL", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(0, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(100, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(200, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(300, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(400, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(500, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(600, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(700, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(800, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""CREATETIME"") VALUES(900, to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) + SELECT 1 FROM DUAL", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle0') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle1') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle2') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle3') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle4') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle5') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle6') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle7') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle8') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle9') + SELECT 1 FROM DUAL", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle0') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle1') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle2') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle3') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle4') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle5') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle6') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle7') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle8') +INTO ""TOPIC_INSERTASTABLE""(""TITLE"") VALUES('newTitle9') + SELECT 1 FROM DUAL", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal(@"INSERT ALL +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(0, 'newTitle0') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(100, 'newTitle1') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(200, 'newTitle2') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(300, 'newTitle3') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(400, 'newTitle4') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(500, 'newTitle5') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(600, 'newTitle6') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(700, 'newTitle7') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(800, 'newTitle8') +INTO ""TOPIC_INSERTASTABLE""(""CLICKS"", ""TITLE"") VALUES(900, 'newTitle9') + SELECT 1 FROM DUAL", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleSelectTest.cs new file mode 100644 index 00000000..e71f0a18 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleSelectTest.cs @@ -0,0 +1,1872 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.Oracle +{ + public class OracleSelectTest + { + + ISelect select => g.oracle.Select(); + + [Table(Name = "tb_topic22")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + class TopicInserts + { + public Guid Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.oracle.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.oracle.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.oracle.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.oracle.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.oracle.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 11; a++) items.Add(new TopicInserts { Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + //Assert.Equal(1, g.oracle.Insert().AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(11, g.oracle.Insert().AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new TopicInserts { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.oracle.Insert(items).ExecuteAffrows()); + + //var dt1 = select.ToDataTable(); + //var dt2 = select.ToDataTable("id, 111222"); + //var dt3 = select.ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + + g.oracle.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.oracle.Select().ToList(); + var testGuidId6 = g.oracle.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.oracle.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.oracle.GetRepository(); + repo.DbContextOptions.EnableCascadeSave = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.oracle.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Single(ddd); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Fact] + public void ToDictionary() + { + g.oracle.Insert(new Topic { Title = "xxx" }).ExecuteAffrows(); + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.oracle.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\"", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" INNER JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.InnerJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a INNER JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + query.ToList(); + + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b ON a.\"TYPEGUID\" = b.\"GUID\" RIGHT JOIN \"TESTTYPEPARENTINFO\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + query.ToList(); + + query = select.RightJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a RIGHT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + query.ToList(); + + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������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\", a.\"CLICKS\", a.\"TYPEGUID\", 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\", a.\"CLICKS\", a.\"TYPEGUID\", 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\", a.\"CLICKS\", a.\"TYPEGUID\", 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\", a.\"CLICKS\", a.\"TYPEGUID\", 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.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b WHERE (b.\"NAME\" = 'typeTitle' AND b.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEPARENTINFO\" c WHERE (c.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c 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\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = :id)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������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\", a.\"CLICKS\", a.\"TYPEGUID\", 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\", a.\"CLICKS\", a.\"TYPEGUID\", 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\", a.\"CLICKS\", a.\"TYPEGUID\", 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\", a.\"CLICKS\", a.\"TYPEGUID\", 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.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" WHERE (a__Type.\"NAME\" = 'typeTitle' AND a__Type.\"GUID\" = a.\"TYPEGUID\")", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a LEFT JOIN \"TESTTYPEINFO\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTINFO\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"NAME\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .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\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c 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\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a WHERE (a.\"CLICKS\" > 100 and a.\"ID\" = :id)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", 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\", a.\"CLICKS\", a.\"TYPEGUID\", 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\", a.\"CLICKS\", a.\"TYPEGUID\", 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\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", 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\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .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\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a, \"TESTTYPEINFO\" b, \"TESTTYPEPARENTINFO\" c", 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\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .Count(out var trycount) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.oracle.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.oracle.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.Offset(10).OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void OrderByRandom() + { + var t1 = select.OrderByRandom().Limit(10).ToSql("1"); + Assert.Equal(@"SELECT t.* FROM (SELECT 1 +FROM ""TB_TOPIC22"" a +ORDER BY dbms_random.value) t WHERE ROWNUM < 11", t1); + var t2 = select.OrderByRandom().Limit(10).ToList(); + } + + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + var subquery = select.ToSql(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, nvl((SELECT sum(b.""ID"") + FROM ""TB_TOPIC22"" b), 0) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + } + [Fact] + public void Min() + { + var subquery = select.ToSql(a => new + { + all = a, + min = select.As("b").Min(b => b.Id), + min2 = select.As("b").Min(b => b.CreateTime) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, nvl((SELECT min(b.""ID"") + FROM ""TB_TOPIC22"" b), 0) as6, nvl((SELECT min(b.""CREATETIME"") + FROM ""TB_TOPIC22"" b), to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) as7 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + min = select.As("b").Min(b => b.Id), + min2 = select.As("b").Min(b => b.CreateTime) + }); + } + [Fact] + public void Max() + { + var subquery = select.ToSql(a => new + { + all = a, + max = select.As("b").Max(b => b.Id), + max2 = select.As("b").Max(b => b.CreateTime) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, nvl((SELECT max(b.""ID"") + FROM ""TB_TOPIC22"" b), 0) as6, nvl((SELECT max(b.""CREATETIME"") + FROM ""TB_TOPIC22"" b), to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6')) as7 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + max = select.As("b").Max(b => b.Id), + max2 = select.As("b").Max(b => b.CreateTime) + }); + } + [Fact] + public void Avg() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + Assert.Equal(@"SELECT a.""ID"" as1, a.""CLICKS"" as2, a.""TYPEGUID"" as3, a.""TITLE"" as4, a.""CREATETIME"" as5, nvl((SELECT avg(b.""ID"") + FROM ""TB_TOPIC22"" b), 0) as6 +FROM ""TB_TOPIC22"" a", subquery); + var subqueryList = select.Limit(10).ToList(a => new + { + all = a, + count = select.As("b").Limit(10).Avg(b => b.Id) + }); + } + [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" +FROM ""TB_TOPIC22"" a +WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" + FROM ""TB_TOPIC22"" b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + + subquery = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.""ID"", a.""CLICKS"", a.""TYPEGUID"", a.""TITLE"", a.""CREATETIME"" +FROM ""TB_TOPIC22"" a +WHERE (((to_char(a.""ID"")) in (SELECT b.""TITLE"" + FROM ""TB_TOPIC22"" b + WHERE ROWNUM < 11)))", subquery); + subqueryList = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (oldname.Length > 16) oldname = oldname.Remove(16); + if (type == typeof(Topic)) return oldname + "_T1"; + else if (type == typeof(TestTypeInfo)) return oldname + "_T2"; + return oldname + "_AT"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON b.\"GUID\" = a.\"TYPEGUID\" AND b.\"NAME\" = 'xxx'", sql); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" AND a__Type.\"NAME\" = 'xxx' LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\" WHERE (a__Type__Parent.\"ID\" = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" a__Type__Parent ON a__Type__Parent.\"ID\" = a__Type.\"PARENTID\"", sql); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a__Type.\"GUID\", a__Type.\"PARENTID\", a__Type.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" a__Type ON a__Type.\"GUID\" = a.\"TYPEGUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON c.\"ID\" = a__Type.\"PARENTID\"", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", b.\"GUID\", b.\"PARENTID\", b.\"NAME\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO_T2\" b ON a.\"TYPEGUID\" = b.\"GUID\" LEFT JOIN \"TESTTYPEPARENTIN_AT\" c ON b.\"PARENTID\" = c.\"ID\"", sql); + + //������϶����㲻�� + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\"", sql); + + query = select.LeftJoin("\"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22_T1\" a LEFT JOIN \"TESTTYPEINFO\" b on b.\"GUID\" = a.\"TYPEGUID\" and b.\"NAME\" = :bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb UNION ALL SELECT * from (SELECT a.\"ID\", a.\"CLICKS\", a.\"TYPEGUID\", a.\"TITLE\", a.\"CREATETIME\" FROM \"TB_TOPIC22\" a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM \"TB_TOPIC22\" a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); + } + + public class TiOtmModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TiOtmModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TiOtmModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TiOtmModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TiOtmModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TiOtmModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TiOtmModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.oracle.Insert(model1).ExecuteIdentity(); + var model2 = new TiOtmModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.oracle.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.oracle.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.oracle.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TiOtmModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.oracle.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TiOtmModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.oracle.Insert(model4s).ExecuteAffrows()); + + var t0 = g.oracle.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.oracle.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + //---- Select ---- + + var at0 = g.oracle.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.oracle.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.oracle.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TiOtmModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TiOtmModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TiOtmModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TiOtmModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TiOtmModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } + public List childs { get; set; } + } + public class TiOtmModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TiOtmModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; + model2.id = (int)g.oracle.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TiOtmModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.oracle.Insert(model3s).ExecuteAffrows()); + + var model1 = new TiOtmModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.oracle.Insert(model1).ExecuteIdentity(); + + var t1 = g.oracle.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.oracle.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + //---- Select ---- + + var at1 = g.oracle.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.oracle.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TiOtmModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.oracle.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.oracle.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.oracle.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.oracle.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.oracle.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.oracle.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.oracle.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.oracle.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.oracle.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.oracle.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + // --- Select --- + + var atags0 = g.oracle.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.oracle.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.oracle.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.oracle.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.oracle.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.oracle.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.oracle.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.oracle.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.oracle.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.oracle.Insert(song3).ExecuteIdentity(); + + g.oracle.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.oracle.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.oracle.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.oracle.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.oracle.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.oracle.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.oracle.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.oracle.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.oracle.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.oracle.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.oracle, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.oracle.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.oracle.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.oracle.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.oracle.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.oracle.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.oracle.Select().Count()); + Assert.Equal(3, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.oracle.Select().Count()); + Assert.Equal(3, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.oracle.Select().Count()); + Assert.Equal(3, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.oracle.Select().Count()); + Assert.Equal(5, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.oracle.Select().Count()); + Assert.Equal(5, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.oracle.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.oracle.Select().Count()); + g.oracle.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.oracle.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.oracle.Select().Count()); + Assert.Equal(5, g.oracle.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + [Fact] + public void ForUpdate() + { + var orm = g.oracle; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a WHERE ROWNUM < 2 for update", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"ID\", a.\"NAME\" FROM \"TOUPD1PK\" a WHERE ROWNUM < 2 for update nowait", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } + + [Fact] + public void ToTreeList() + { + var fsql = g.oracle; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableCascadeSave = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); + Assert.Equal(4, t3.Count); + Assert.Equal("100000", t3[0].Code); + Assert.Equal("110000", t3[1].Code); + Assert.Equal("110100", t3[2].Code); + Assert.Equal("110101", t3[3].Code); + + t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); + Assert.Equal(3, t3.Count); + Assert.Equal("110000", t3[0].Code); + Assert.Equal("110100", t3[1].Code); + Assert.Equal("110101", t3[2].Code); + + var t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name).OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国", t4[0].path); + Assert.Equal("中国 -> 北京", t4[1].path); + Assert.Equal("中国 -> 北京 -> 北京市", t4[2].path); + Assert.Equal("中国 -> 北京 -> 东城区", t4[3].path); + + t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name + "[" + a.Code + "]").OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国[100000]", t4[0].path); + Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); + + var select = fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte() + //.OrderBy("a.cte_level desc") //递归层级 + ; + // var list = select.ToList(); //自己调试看查到的数据 + select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + Assert.Equal(855, fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Distinct().First(a => a.testint)); + + Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + Assert.False(fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Any()); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + + public int testint { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleUpdateTest.cs new file mode 100644 index 00000000..562f54d3 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/Curd/OracleUpdateTest.cs @@ -0,0 +1,191 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using Xunit; + +namespace FreeSql.Tests.Custom.Oracle +{ + public class OracleUpdateTest + { + IUpdate update => g.oracle.Update(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.oracle.Update().ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } + + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = NULL, \"TITLE\" = 'newtitle', \"CREATETIME\" = to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; + + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = CASE \"ID\" WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END, \"TITLE\" = CASE \"ID\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END, \"CREATETIME\" = CASE \"ID\" WHEN 1 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 2 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 3 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 4 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 5 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 6 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 7 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 8 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 9 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHEN 10 THEN to_timestamp('0001-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = CASE \"ID\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CREATETIME\" = to_timestamp('2020-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.oracle.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + + var uuids = new[] + { + new tssi01{tint = 1, title = "title01"}, + new tssi01{tint = 2, title = "title02"}, + new tssi01{tint = 3, title = "title03"}, + }; + g.oracle.Insert(uuids).ExecuteAffrows(); + g.oracle.Update().SetSource(uuids).ExecuteAffrows(); + + var tssi01tb = g.oracle.DbFirst.GetTableByName("tssi01"); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } + } + [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE \"TSSI01\" SET \"TINT\" = 10 WHERE (\"ID\" = '00000000-0000-0000-0000-000000000000')", + g.oracle.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false, DbType = "nvarchar2(36)")] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle' WHERE (\"ID\" = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"TITLE\" = 'newtitle', \"CREATETIME\" = to_timestamp('2020-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(nvl(\"CLICKS\", 0) * 10 / 1) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(nvl(\"CLICKS\", 0) * 10 / 1) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = (\"ID\" - 10) WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = trunc(\"CLICKS\" * 10 / 1) WHERE (\"ID\" = 1)", sql); + + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = case when \"CREATETIME\" > to_timestamp('2000-01-01 00:00:00.000000','YYYY-MM-DD HH24:MI:SS.FF6') then 1 else 2 end WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"ID\" = 10 WHERE (\"ID\" = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = NULL WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + ?", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET clicks = clicks + ? WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET \"CLICKS\" = 1, \"TITLE\" = 'xxx' WHERE (\"ID\" = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + + sql = update.Where("id = ?", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (id = ?)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"TB_TOPIC\" SET title='newtitle' WHERE (\"ID\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + + } + [Fact] + public void ExecuteUpdated() + { + + } + + [Fact] + public void AsTable() + { + Assert.Null(g.oracle.Update().ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test' \r\nWHERE (\"ID\" IN (1,2))", g.oracle.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" IN (1,2))", g.oracle.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"TB_TOPICASTABLE\" SET title='test1' \r\nWHERE (\"ID\" = 1)", g.oracle.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..7833d682 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/BoolNullableTest.cs @@ -0,0 +1,1571 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Custom.OracleMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.oracle; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/BoolTest.cs new file mode 100644 index 00000000..5f9b117f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/BoolTest.cs @@ -0,0 +1,1105 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Custom.OracleMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.oracle; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..5bd75cad --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Custom.OracleMapType +{ + public class DateTimeOffSetTest + { + class Dtos_dt + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtofnil_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.oracle; + var item = new Dtos_dt { dtos_to_dt = DateTimeOffset.Now, dtofnil_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtofnil_to_dt.Value.ToString("g"), find.dtofnil_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/EnumTest.cs new file mode 100644 index 00000000..85d204e7 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/EnumTest.cs @@ -0,0 +1,261 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Custom.OracleMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.oracle; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.oracle; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() + { + //insert + var orm = g.oracle; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.oracle; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/ToStringTest.cs new file mode 100644 index 00000000..c9a60ff8 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/MapType/ToStringTest.cs @@ -0,0 +1,570 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Custom.OracleMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.oracle; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleAdo/OracleAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleAdo/OracleAdoTest.cs new file mode 100644 index 00000000..623c4c31 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleAdo/OracleAdoTest.cs @@ -0,0 +1,71 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Custom.Oracle +{ + public class OracleAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.oracle.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() + { + var t2 = g.oracle.Ado.SlavePools.Count; + } + + [Fact] + public void ExecuteTest() + { + Assert.True(g.oracle.Ado.ExecuteConnectTest()); + } + [Fact] + public void ExecuteReader() + { + + } + [Fact] + public void ExecuteArray() + { + + } + [Fact] + public void ExecuteNonQuery() + { + + } + [Fact] + public void ExecuteScalar() + { + + } + + [Fact] + public void Query() + { + + var t3 = g.oracle.Ado.Query("select * from \"TB_TOPIC\""); + + var t4 = g.oracle.Ado.Query<(int, string, string)>("select * from \"TB_TOPIC\""); + + var t5 = g.oracle.Ado.Query("select * from \"TB_TOPIC\""); + } + + [Fact] + public void QueryMultipline() + { + //var t3 = g.oracle.Ado.Query("select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\"; select * from \"TB_TOPIC\""); + } + + class xxx + { + public int Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleAopTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleAopTest.cs new file mode 100644 index 00000000..18e53324 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Custom.Oracle +{ + public class OracleAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var date = DateTime.Now.Date; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now.Date; + }; + g.oracle.Aop.AuditValue += audit; + + g.oracle.Insert(item).ExecuteAffrows(); + + g.oracle.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime, date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleCodeFirstTest.cs new file mode 100644 index 00000000..36a0f209 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleCodeFirstTest.cs @@ -0,0 +1,336 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Custom.Oracle +{ + public class OracleCodeFirstTest + { + [Fact] + public void Test_0String() + { + var fsql = g.oracle; + fsql.Delete().Where("1=1").ExecuteAffrows(); + + Assert.Equal(1, fsql.Insert(new test_0string01 { name = @"1.0000\0.0000\0.0000\0.0000\1.0000\0.0000" }).ExecuteAffrows()); + Assert.Equal(1, fsql.Insert(new test_0string01 { name = @"1.0000\0.0000\0.0000\0.0000\1.0000\0.0000" }).NoneParameter().ExecuteAffrows()); + + var list = fsql.Select().ToList(); + Assert.Equal(2, list.Count); + Assert.Equal(@"1.0000\0.0000\0.0000\0.0000\1.0000\0.0000", list[0].name); + Assert.Equal(@"1.0000\0.0000\0.0000\0.0000\1.0000\0.0000", list[1].name); + } + class test_0string01 + { + public Guid id { get; set; } + public string name { get; set; } + } + + [Fact] + public void StringLength() + { + var dll = g.oracle.CodeFirst.GetComparisonDDLStatements(); + g.oracle.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } + } + + [Fact] + public void 数字表_字段() + { + var sql = g.oracle.CodeFirst.GetComparisonDDLStatements<测试数字表>(); + g.oracle.CodeFirst.SyncStructure<测试数字表>(); + + var item = new 测试数字表 + { + 标题 = "测试标题", + 创建时间 = DateTime.Now + }; + Assert.Equal(1, g.oracle.Insert<测试数字表>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.编号); + var item2 = g.oracle.Select<测试数字表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新"; + Assert.Equal(1, g.oracle.Update<测试数字表>().SetSource(item).ExecuteAffrows()); + item2 = g.oracle.Select<测试数字表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新_repo"; + var repo = g.oracle.GetRepository<测试数字表>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.oracle.Select<测试数字表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.oracle.Select<测试数字表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + } + [Table(Name = "123tb")] + class 测试数字表 + { + [Column(IsPrimary = true, Name = "123id")] + public Guid 编号 { get; set; } + + [Column(Name = "123title")] + public string 标题 { get; set; } + + [Column(Name = "123time")] + public DateTime 创建时间 { get; set; } + } + + [Fact] + public void 中文表_字段() + { + var sql = g.oracle.CodeFirst.GetComparisonDDLStatements<测试中文表>(); + g.oracle.CodeFirst.SyncStructure<测试中文表>(); + + var item = new 测试中文表 + { + 标题 = "测试标题", + 创建时间 = DateTime.Now + }; + Assert.Equal(1, g.oracle.Insert<测试中文表>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.编号); + var item2 = g.oracle.Select<测试中文表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新"; + Assert.Equal(1, g.oracle.Update<测试中文表>().SetSource(item).ExecuteAffrows()); + item2 = g.oracle.Select<测试中文表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新_repo"; + var repo = g.oracle.GetRepository<测试中文表>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.oracle.Select<测试中文表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.oracle.Select<测试中文表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + } + class 测试中文表 + { + [Column(IsPrimary = true)] + public Guid 编号 { get; set; } + + public string 标题 { get; set; } + + public DateTime 创建时间 { get; set; } + } + + [Fact] + public void AddUniques() + { + var sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); + g.oracle.CodeFirst.SyncStructure(); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index22", "group, index22", true)] + class AddUniquesInfo + { + public Guid id { get; set; } + public string phone { get; set; } + + public string group { get; set; } + public int index { get; set; } + public string index22 { get; set; } + } + [Fact] + public void AddField() + { + var sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); + + var id = g.oracle.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + + //var inserted = g.oracle.Insert().AppendData(new TopicAddField { }).ExecuteInserted(); + } + + [Table(Name = "TopicAddField", OldName = "xxxtb.TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public string name { get; set; } + + [Column(DbType = "varchar2(200 char) not null", OldName = "title")] + public string title2 { get; set; } = "10"; + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() + { + var sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); + Assert.True(string.IsNullOrEmpty(sql)); //测试运行两次后 + //sql = g.oracle.CodeFirst.GetComparisonDDLStatements(); + } + + IInsert insert => g.oracle.Insert(); + ISelect select => g.oracle.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + for (var a = 0; a < 100; a++) + { + try //ERROR [23000] [Oracle][ODBC][Ora]ORA-00001: 违反唯一约束条件 (1ODBC.1ODBC_TB_ALLTYPE_pk2) + { + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + break; + } + catch + { + } + } + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + Bool = true, + BoolNullable = true, + Byte = 255, + ByteNullable = 127, + Bytes = Encoding.UTF8.GetBytes("我是中国人"), + DateTime = DateTime.Now, + DateTimeNullable = DateTime.Now.AddHours(-1), + Decimal = 99.99M, + DecimalNullable = 99.98M, + Double = 999.99, + DoubleNullable = 999.98, + Enum1 = TableAllTypeEnumType1.e5, + Enum1Nullable = TableAllTypeEnumType1.e3, + Enum2 = TableAllTypeEnumType2.f2, + Enum2Nullable = TableAllTypeEnumType2.f3, + Float = 19.99F, + FloatNullable = 19.98F, + Guid = Guid.NewGuid(), + GuidNullable = Guid.NewGuid(), + Int = int.MaxValue, + IntNullable = int.MinValue, + SByte = 100, + SByteNullable = 99, + Short = short.MaxValue, + ShortNullable = short.MinValue, + String = "我是中国人string'\\?!@#$%^&*()_+{}}{~?><<>", + Char = 'X', + TimeSpan = TimeSpan.FromSeconds(999), + TimeSpanNullable = TimeSpan.FromSeconds(60), + UInt = uint.MaxValue, + UIntNullable = uint.MinValue, + ULong = ulong.MaxValue, + ULongNullable = ulong.MinValue, + UShort = ushort.MaxValue, + UShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteIdentity(); + + item2.Id = (int)insert.AppendData(item2).ExecuteIdentity(); + var newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); + + item2.Id = (int)insert.NoneParameter().AppendData(item2).ExecuteIdentity(); + newitem2 = select.Where(a => a.Id == item2.Id).ToOne(); + Assert.Equal(item2.String, newitem2.String); + Assert.Equal(item2.Char, newitem2.Char); + + var items = select.ToList(); + var itemstb = select.ToDataTable(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTime DateTime { get; set; } + public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } + public string String { get; set; } + public char Char { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + public DateTime? DateTimeNullable { get; set; } + public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleDbFirstTest.cs new file mode 100644 index 00000000..04118c5d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleDbFirstTest.cs @@ -0,0 +1,65 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Custom.Oracle +{ + public class OracleDbFirstTest + { + [Fact] + public void GetDatabases() + { + var t1 = g.oracle.DbFirst.GetDatabases(); + } + + [Fact] + public void GetTablesByDatabase() + { + var t2 = g.oracle.DbFirst.GetTablesByDatabase(); + Assert.True(t2.Count > 0); + //var tb = g.oracle.Ado.ExecuteArray(System.Data.CommandType.Text, "select * from \"tb_dbfirst\""); + } + + [Fact] + public void GetTableByName() + { + var fsql = g.oracle; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("1odbc.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); + } + + [Fact] + public void ExistsTable() + { + var fsql = g.oracle; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("1odbc.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("1odbc.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("1odbc.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("11odbcuser.test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("1odbc.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("1odbc.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "1odbc.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("1odbc.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("1odbc.test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table \"1ODBC\".test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/ConvertTest.cs new file mode 100644 index 00000000..011af008 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/ConvertTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.OracleExpression +{ + public class ConvertTest + { + + ISelect select => g.oracle.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() + { + var data = new List(); + //data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + //data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/DateTimeTest.cs new file mode 100644 index 00000000..037caa22 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/DateTimeTest.cs @@ -0,0 +1,732 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.OracleExpression +{ + public class DateTimeTest + { + + ISelect select => g.oracle.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } = DateTime.Now; + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInf1")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now.ToString())).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + //g.oracle.Insert(new Topic()).ExecuteAffrows(); + //var dtn = DateTime.Parse("2020-1-1 0:0:0"); + //var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + // .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + // .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + // .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + // .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + //foreach (var dt in dts) + //{ + // Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + // Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + // Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + // Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + // Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + // Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + // Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + // Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + // Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + // Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + // Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + // Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + // Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + // Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + // Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s"))); + //} + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((extract(day from (systimestamp-a."CREATETIME"))*86400+extract(hour from (systimestamp-a."CREATETIME"))*3600+extract(minute from (systimestamp-a."CREATETIME"))*60+extract(second from (systimestamp-a."CREATETIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((extract(day from (systimestamp-a__Type."TIME"))*86400+extract(hour from (systimestamp-a__Type."TIME"))*3600+extract(minute from (systimestamp-a__Type."TIME"))*60+extract(second from (systimestamp-a__Type."TIME"))) > 0) + + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((extract(day from (systimestamp-a__Type__Parent."TIME2"))*86400+extract(hour from (systimestamp-a__Type__Parent."TIME2"))*3600+extract(minute from (systimestamp-a__Type__Parent."TIME2"))*60+extract(second from (systimestamp-a__Type__Parent."TIME2"))) > 0) + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a."TITLE", a."CREATETIME" + //FROM "TB_TOPIC111333" a + //WHERE ((a."CREATETIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //WHERE ((a__Type."TIME"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + //SELECT a."ID", a."CLICKS", a."TYPEGUID", a__Type."GUID", a__Type."PARENTID", a__Type."NAME", a__Type."TIME", a."TITLE", a."CREATETIME" + + //FROM "TB_TOPIC111333" a + //LEFT JOIN "TESTTYPEINFO333" a__Type ON a__Type."GUID" = a."TYPEGUID" + //LEFT JOIN "TESTTYPEPARENTINF1" a__Type__Parent ON a__Type__Parent."ID" = a__Type."PARENTID" + //WHERE ((a__Type__Parent."TIME2"-numtodsinterval((1)*86400,'second')) > a."CREATETIME") + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + //data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/MathTest.cs new file mode 100644 index 00000000..d63e88b8 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/MathTest.cs @@ -0,0 +1,156 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.OracleExpression +{ + public class MathTest + { + + ISelect select => g.oracle.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + var data = new List(); + data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks % 5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks % 5)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/OtherTest.cs new file mode 100644 index 00000000..2d0bc82c --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/OtherTest.cs @@ -0,0 +1,165 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.OracleExpression +{ + public class OtherTest + { + + ISelect select => g.oracle.Select(); + + public OtherTest() + { + } + + [Fact] + public void Div() + { + var t1 = select.Where(a => a.Int / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.Long / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.Short / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.Int / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.Long / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.Short / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.Double / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.Decimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.Float / 3 > 3).Limit(10).ToList(); + } + + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.Bool == true).ToList(); + var t2 = select.Where(a => a.Bool != true).ToList(); + var t3 = select.Where(a => a.Bool == false).ToList(); + var t4 = select.Where(a => !a.Bool).ToList(); + var t5 = select.Where(a => a.Bool).ToList(); + var t51 = select.WhereCascade(a => a.Bool).Limit(10).ToList(); + + var t11 = select.Where(a => a.BoolNullable == true).ToList(); + var t22 = select.Where(a => a.BoolNullable != true).ToList(); + var t33 = select.Where(a => a.BoolNullable == false).ToList(); + var t44 = select.Where(a => !a.BoolNullable.Value).ToList(); + var t55 = select.Where(a => a.BoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.Bool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.Bool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.Bool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.Bool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.Bool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.BoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.BoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.BoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.BoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.Bool == true && a.Id > 0 && a.Bool == true).ToList(); + var t22222 = select.Where(a => a.Bool != true && a.Id > 0 && a.Bool != true).ToList(); + var t33333 = select.Where(a => a.Bool == false && a.Id > 0 && a.Bool == false).ToList(); + var t44444 = select.Where(a => !a.Bool && a.Id > 0 && !a.Bool).ToList(); + var t55555 = select.Where(a => a.Bool && a.Id > 0 && a.Bool).ToList(); + + var t111111 = select.Where(a => a.BoolNullable == true && a.Id > 0 && a.BoolNullable == true).ToList(); + var t222222 = select.Where(a => a.BoolNullable != true && a.Id > 0 && a.BoolNullable != true).ToList(); + var t333333 = select.Where(a => a.BoolNullable == false && a.Id > 0 && a.BoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.BoolNullable.Value && a.Id > 0 && !a.BoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.BoolNullable.Value && a.Id > 0 && a.BoolNullable.Value).ToList(); + } + + [Fact] + public void Array() + { + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.Int)).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql1122 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + //var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.Int) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.Int)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + //var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.Int) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.Int)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.Int)).ToList(); + //var sql112222 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.Int)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.Int)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.Int) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.Int)).ToList(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + public string id2 { get; set; } = "id2=10"; + + public bool Bool { get; set; } + public sbyte SByte { get; set; } + public short Short { get; set; } + public int Int { get; set; } + public long Long { get; set; } + public byte Byte { get; set; } + public ushort UShort { get; set; } + public uint UInt { get; set; } + public ulong ULong { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } + public TimeSpan TimeSpan { get; set; } + public DateTime DateTime { get; set; } + public DateTime DateTimeOffSet { get; set; } + public byte[] Bytes { get; set; } + public string String { get; set; } + public Guid Guid { get; set; } + + public bool? BoolNullable { get; set; } + public sbyte? SByteNullable { get; set; } + public short? ShortNullable { get; set; } + public int? IntNullable { get; set; } + public long? testFielLongNullable { get; set; } + public byte? ByteNullable { get; set; } + public ushort? UShortNullable { get; set; } + public uint? UIntNullable { get; set; } + public ulong? ULongNullable { get; set; } + public double? DoubleNullable { get; set; } + public float? FloatNullable { get; set; } + public decimal? DecimalNullable { get; set; } + public TimeSpan? TimeSpanNullable { get; set; } + public DateTime? DateTimeNullable { get; set; } + public DateTime? DateTimeOffSetNullable { get; set; } + public Guid? GuidNullable { get; set; } + + public TableAllTypeEnumType1 Enum1 { get; set; } + public TableAllTypeEnumType1? Enum1Nullable { get; set; } + public TableAllTypeEnumType2 Enum2 { get; set; } + public TableAllTypeEnumType2? Enum2Nullable { get; set; } + } + + public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } + [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/StringTest.cs new file mode 100644 index 00000000..25a97a04 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/StringTest.cs @@ -0,0 +1,827 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.OracleExpression +{ + public class StringTest + { + + ISelect select => g.oracle.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.oracle.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + [Fact] + public void StringJoin() + { + var fsql = g.oracle; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + + [Fact] + public void Format() + { + var item = g.oracle.GetRepository().Insert(new Topic { Clicks = 101, Title = "我是中国人101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||'' as1, ''||nvl((a.""ID"" + 1), '')||'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + + [Fact] + public void Format4() + { + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var item = g.oracle.GetRepository().Insert(new Topic { Clicks = 101, Title = "我是中国人101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT 'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||''||nvl(a.""TITLE"", '')||'' as1, ''||nvl((a.""ID"" + 1), '')||'x'||nvl((a.""ID"" + 1), '')||'z-'||nvl(to_char(a.""CREATETIME"",'YYYYMM'), '')||''||nvl(a.""TITLE"", '')||''||nvl(a.""TITLE"", '')||'' as2 +FROM ""TB_TOPIC"" a +WHERE (a.""ID"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + + + list.Add(select.Where(a => a.Title.Contains("%")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + "%")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1 + "%")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name + "%")).ToList()); + + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa" + "%")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + "%")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1 + "%")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name + "%")).ToList()); + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/TimeSpanTest.cs new file mode 100644 index 00000000..68e0968e --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/Oracle/OracleExpression/TimeSpanTest.cs @@ -0,0 +1,293 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.OracleExpression +{ + public class TimeSpanTest + { + + ISelect select => g.oracle.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } + + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/OnConflictDoUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/OnConflictDoUpdateTest.cs new file mode 100644 index 00000000..c24a1f41 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/OnConflictDoUpdateTest.cs @@ -0,0 +1,158 @@ +using FreeSql.DataAnnotations; +using FreeSql.Custom.PostgreSQL; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQL +{ + public class OnConflictDoUpdateTest + { + class TestOnConflictDoUpdateInfo + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string title { get; set; } + public DateTime? time { get; set; } + } + + [Fact] + public void ExecuteAffrows() + { + g.pgsql.Delete(new[] { 100, 101, 102 }).ExecuteAffrows(); + var odku1 = new CustomPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"", ""time"") VALUES(100, 'title-100', '2000-01-01 00:00:00.000000') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = EXCLUDED.""time""", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new CustomPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 100, title = "title-100", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 101, title = "title-101", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 102, title = "title-102", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"", ""time"") VALUES(100, 'title-100', '2000-01-01 00:00:00.000000'), (101, 'title-101', '2000-01-01 00:00:00.000000'), (102, 'title-102', '2000-01-01 00:00:00.000000') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = EXCLUDED.""time""", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void IgnoreColumns() + { + g.pgsql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + var odku1 = new CustomPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(200, 'title-200') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = '2000-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new CustomPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = CASE EXCLUDED.""id"" +WHEN 200 THEN '2000-01-01 00:00:00.000000' +WHEN 201 THEN '2000-01-01 00:00:00.000000' +WHEN 202 THEN '2000-01-01 00:00:00.000000' END::timestamp", odku2.ToSql()); + odku2.ExecuteAffrows(); + + + g.pgsql.Delete(new[] { 200, 201, 202 }).ExecuteAffrows(); + odku1 = new CustomPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()).IgnoreColumns(a => a.title); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(200, 'title-200') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = '2000-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = new CustomPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 200, title = "title-200", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 201, title = "title-201", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 202, title = "title-202", time = DateTime.Parse("2000-01-01") } + }).IgnoreColumns(a => a.time).NoneParameter().InsertIdentity()).IgnoreColumns(a => a.title); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(200, 'title-200'), (201, 'title-201'), (202, 'title-202') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = CASE EXCLUDED.""id"" +WHEN 200 THEN '2000-01-01 00:00:00.000000' +WHEN 201 THEN '2000-01-01 00:00:00.000000' +WHEN 202 THEN '2000-01-01 00:00:00.000000' END::timestamp", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void UpdateColumns() + { + g.pgsql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + var odku1 = new CustomPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(300, 'title-300') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = '2000-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new CustomPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON CONFLICT(""id"") DO UPDATE SET +""title"" = EXCLUDED.""title"", +""time"" = CASE EXCLUDED.""id"" +WHEN 300 THEN '2000-01-01 00:00:00.000000' +WHEN 301 THEN '2000-01-01 00:00:00.000000' +WHEN 302 THEN '2000-01-01 00:00:00.000000' END::timestamp", odku2.ToSql()); + odku2.ExecuteAffrows(); + + + g.pgsql.Delete(new[] { 300, 301, 302 }).ExecuteAffrows(); + odku1 = new CustomPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()).UpdateColumns(a => a.time); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(300, 'title-300') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = '2000-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + odku2 = new CustomPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 300, title = "title-300", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 301, title = "title-301", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 302, title = "title-302", time = DateTime.Parse("2000-01-01") } + }).InsertColumns(a => a.title).NoneParameter().InsertIdentity()).UpdateColumns(a => a.time); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"") VALUES(300, 'title-300'), (301, 'title-301'), (302, 'title-302') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = CASE EXCLUDED.""id"" +WHEN 300 THEN '2000-01-01 00:00:00.000000' +WHEN 301 THEN '2000-01-01 00:00:00.000000' +WHEN 302 THEN '2000-01-01 00:00:00.000000' END::timestamp", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + + [Fact] + public void Set() + { + g.pgsql.Delete(new[] { 400, 401, 402 }).ExecuteAffrows(); + var odku1 = new CustomPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }).NoneParameter().InsertIdentity()).Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = '2020-01-01 00:00:00.000000'", odku1.ToSql()); + Assert.Equal(1, odku1.ExecuteAffrows()); + + var odku2 = new CustomPostgreSQLOnConflictDoUpdate(g.pgsql.Insert(new[] { + new TestOnConflictDoUpdateInfo { id = 400, title = "title-400", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 401, title = "title-401", time = DateTime.Parse("2000-01-01") }, + new TestOnConflictDoUpdateInfo { id = 402, title = "title-402", time = DateTime.Parse("2000-01-01") } + }).NoneParameter().InsertIdentity()).Set(a => a.time, DateTime.Parse("2020-1-1")); + Assert.Equal(@"INSERT INTO ""testonconflictdoupdateinfo""(""id"", ""title"", ""time"") VALUES(400, 'title-400', '2000-01-01 00:00:00.000000'), (401, 'title-401', '2000-01-01 00:00:00.000000'), (402, 'title-402', '2000-01-01 00:00:00.000000') +ON CONFLICT(""id"") DO UPDATE SET +""time"" = '2020-01-01 00:00:00.000000'", odku2.ToSql()); + odku2.ExecuteAffrows(); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLDeleteTest.cs new file mode 100644 index 00000000..38d1c3e6 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLDeleteTest.cs @@ -0,0 +1,105 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQL +{ + public class PostgreSQLDeleteTest + { + + IDelete delete => g.pgsql.Delete(); + + [Table(Name = "tb_topic_del")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.pgsql.Delete().ToSql()); + var sql = g.pgsql.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" IN (1,2))", sql); + + sql = g.pgsql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); + + sql = g.pgsql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" IN (1,2))", sql); + + sql = g.pgsql.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); + + sql = g.pgsql.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM \"multipktopic\" WHERE (\"id1\" = 1 AND \"id2\" = 10 OR \"id1\" = 2 AND \"id2\" = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); + + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (id = @id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + + var id = g.pgsql.Insert(new Topic { Title = "xxxx" }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { + + delete.Where(a => a.Id > 0).ExecuteDeleted(); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.pgsql.Delete().ToSql()); + var sql = g.pgsql.Delete(new[] { 1, 2 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" IN (1,2))", sql); + + sql = g.pgsql.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1)", sql); + + sql = g.pgsql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" IN (1,2))", sql); + + sql = g.pgsql.Delete(new { id = 1 }).AsTable(a => "TopicAsTable").ToSql(); + Assert.Equal("DELETE FROM \"topicastable\" WHERE (\"id\" = 1)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs new file mode 100644 index 00000000..ce8a247b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLInsertOrUpdateIfExistsDoNotingTest.cs @@ -0,0 +1,266 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQL +{ + public class PostgreSQLInsertOrUpdateIfExistsDoNotingTest + { + IFreeSql fsql => g.pgsql; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(2) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1), (2), (3), (4) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb01""(""id"") VALUES(1), (2), (3), (4) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '01') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '011') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(2, '02') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb02""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '01') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '011') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(2, '02') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""name"") VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb022""(""id"", ""name"") VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004') +ON CONFLICT(""id"") DO NOTHING + +; + +INSERT INTO ""tbioudb022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '011') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(2, '02', '02') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004') +ON CONFLICT(""id1"", ""id2"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '011', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(2, '02', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp), (2, '02', 0, current_timestamp), (3, '03', 0, current_timestamp), (4, '04', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbioudb04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '001', 0, current_timestamp), (2, '002', 0, current_timestamp), (3, '003', 0, current_timestamp), (4, '004', 0, current_timestamp) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs new file mode 100644 index 00000000..227b2214 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLInsertOrUpdateTest.cs @@ -0,0 +1,292 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQL +{ + public class PostgreSQLInsertOrUpdateTest + { + IFreeSql fsql => g.pgsql; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(1) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(1) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(2) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(1), (2), (3), (4) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou01""(""id"") VALUES(1), (2), (3), (4) +ON CONFLICT(""id"") DO NOTHING", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbiou01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(1, '01') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(1, '011') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(2, '02') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou02""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '01') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '011') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(2, '02') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '01'), (2, '02'), (3, '03'), (4, '04') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '001'), (2, '002'), (3, '003'), (4, '004') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('01'), ('02'), ('03'), ('04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""name"") VALUES('001'), ('002'), ('003'), ('004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou022""(""id"", ""name"") VALUES(1, '100001'), (2, '100002'), (3, '100003'), (4, '100004') +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"" + +; + +INSERT INTO ""tbiou022""(""name"") VALUES('00001'), ('00002'), ('00003'), ('00004')", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01') +ON CONFLICT(""id1"", ""id2"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '011') +ON CONFLICT(""id1"", ""id2"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(2, '02', '02') +ON CONFLICT(""id1"", ""id2"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '01'), (2, '02', '02'), (3, '03', '03'), (4, '04', '04') +ON CONFLICT(""id1"", ""id2"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou03""(""id1"", ""id2"", ""name"") VALUES(1, '01', '001'), (2, '02', '002'), (3, '03', '003'), (4, '04', '004') +ON CONFLICT(""id1"", ""id2"") DO UPDATE SET +""name"" = EXCLUDED.""name""", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp) +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"", +""version"" = ""tbiou04"".""version"" + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '011', 0, current_timestamp) +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"", +""version"" = ""tbiou04"".""version"" + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(2, '02', 0, current_timestamp) +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"", +""version"" = ""tbiou04"".""version"" + 1", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '01', 0, current_timestamp), (2, '02', 0, current_timestamp), (3, '03', 0, current_timestamp), (4, '04', 0, current_timestamp) +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"", +""version"" = ""tbiou04"".""version"" + 1", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO ""tbiou04""(""id"", ""name"", ""version"", ""createtime"") VALUES(1, '001', 0, current_timestamp), (2, '002', 0, current_timestamp), (3, '003', 0, current_timestamp), (4, '004', 0, current_timestamp) +ON CONFLICT(""id"") DO UPDATE SET +""name"" = EXCLUDED.""name"", +""version"" = ""tbiou04"".""version"" + 1", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLInsertTest.cs new file mode 100644 index 00000000..9890a349 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLInsertTest.cs @@ -0,0 +1,141 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQL +{ + public class PostgreSQLInsertTest + { + + IInsert insert => g.pgsql.Insert(); + + [Table(Name = "tb_topic_insert")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\", \"createtime\") VALUES(0, 'newtitle0', '0001-01-01 00:00:00.000000')", sql); + + sql = insert.AppendData(items).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\", \"createtime\") VALUES(0, 'newtitle0', '0001-01-01 00:00:00.000000'), (100, 'newtitle1', '0001-01-01 00:00:00.000000'), (200, 'newtitle2', '0001-01-01 00:00:00.000000'), (300, 'newtitle3', '0001-01-01 00:00:00.000000'), (400, 'newtitle4', '0001-01-01 00:00:00.000000'), (500, 'newtitle5', '0001-01-01 00:00:00.000000'), (600, 'newtitle6', '0001-01-01 00:00:00.000000'), (700, 'newtitle7', '0001-01-01 00:00:00.000000'), (800, 'newtitle8', '0001-01-01 00:00:00.000000'), (900, 'newtitle9', '0001-01-01 00:00:00.000000')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"title\") VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + } + + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"title\") VALUES('newtitle0'), ('newtitle1'), ('newtitle2'), ('newtitle3'), ('newtitle4'), ('newtitle5'), ('newtitle6'), ('newtitle7'), ('newtitle8'), ('newtitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\", \"title\") VALUES(0, 'newtitle0'), (100, 'newtitle1'), (200, 'newtitle2'), (300, 'newtitle3'), (400, 'newtitle4'), (500, 'newtitle5'), (600, 'newtitle6'), (700, 'newtitle7'), (800, 'newtitle8'), (900, 'newtitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + Assert.Equal("INSERT INTO \"tb_topic_insert\"(\"clicks\") VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + + g.pgsql.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.pgsql.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.pgsql.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicIgnoreColumns")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + } + [Fact] + public void ExecuteInserted() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + insert.AppendData(items.First()).ExecuteInserted(); + } + + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newTitle{a}", Clicks = a * 100 }); + + var sql = insert.AppendData(items.First()).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\", \"createtime\") VALUES(0, 'newTitle0', '0001-01-01 00:00:00.000000')", sql); + + sql = insert.AppendData(items).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\", \"createtime\") VALUES(0, 'newTitle0', '0001-01-01 00:00:00.000000'), (100, 'newTitle1', '0001-01-01 00:00:00.000000'), (200, 'newTitle2', '0001-01-01 00:00:00.000000'), (300, 'newTitle3', '0001-01-01 00:00:00.000000'), (400, 'newTitle4', '0001-01-01 00:00:00.000000'), (500, 'newTitle5', '0001-01-01 00:00:00.000000'), (600, 'newTitle6', '0001-01-01 00:00:00.000000'), (700, 'newTitle7', '0001-01-01 00:00:00.000000'), (800, 'newTitle8', '0001-01-01 00:00:00.000000'), (900, 'newTitle9', '0001-01-01 00:00:00.000000')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"title\") VALUES('newTitle0'), ('newTitle1'), ('newTitle2'), ('newTitle3'), ('newTitle4'), ('newTitle5'), ('newTitle6'), ('newTitle7'), ('newTitle8'), ('newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\") VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"title\") VALUES('newTitle0'), ('newTitle1'), ('newTitle2'), ('newTitle3'), ('newTitle4'), ('newTitle5'), ('newTitle6'), ('newTitle7'), ('newTitle8'), ('newTitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\") VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\", \"title\") VALUES(0, 'newTitle0'), (100, 'newTitle1'), (200, 'newTitle2'), (300, 'newTitle3'), (400, 'newTitle4'), (500, 'newTitle5'), (600, 'newTitle6'), (700, 'newTitle7'), (800, 'newTitle8'), (900, 'newTitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).AsTable(a => "Topic_InsertAsTable").ToSql(); + Assert.Equal("INSERT INTO \"topic_insertastable\"(\"clicks\") VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLSelectTest.cs new file mode 100644 index 00000000..6f003f3d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLSelectTest.cs @@ -0,0 +1,1932 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQL +{ + public class PostgreSQLSelectTest + { + + ISelect select => g.pgsql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.pgsql.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a__Parent.`Id` as3, a__Parent.`Parent_id` as4, a__Parent.`Ddd`, a__Parent.`Name`, a.`Ddd` as7, a.`Name` as8 + //FROM `Tag` a + //LEFT JOIN `Tag` a__Parent ON a__Parent.`Id` = a.`Parent_id` + //LEFT JOIN `Tag` a__Parent__Parent ON a__Parent__Parent.`Id` = a__Parent.`Parent_id` + //WHERE (a__Parent__Parent.`Name` = '粤语') + + //OneToMany + var t1 = g.pgsql.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.`Id`, a.`Parent_id`, a.`Ddd`, a.`Name` + //FROM `Tag` a + //WHERE (exists(SELECT 1 + // FROM `Tag` t + // LEFT JOIN `Tag` t__Parent ON t__Parent.`Id` = t.`Parent_id` + // WHERE (t__Parent.`Id` = 10) AND (t.`Parent_id` = a.`Id`) + // limit 0,1)) + + //ManyToMany + var t2 = g.pgsql.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.`Id`, a.`Create_time`, a.`Is_deleted`, a.`Title`, a.`Url` + //FROM `Song` a + //WHERE(exists(SELECT 1 + // FROM `Song_tag` Mt_Ms + // WHERE(Mt_Ms.`Song_id` = a.`Id`) AND(exists(SELECT 1 + // FROM `Tag` t + // WHERE(t.`Name` = '国语') AND(t.`Id` = Mt_Ms.`Tag_id`) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.pgsql.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.pgsql.Select().Limit(10).ToList(); + } + + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Single(g.pgsql.Insert().AppendData(items.First()).ExecuteInserted()); + Assert.Equal(10, g.pgsql.Insert().AppendData(items).ExecuteInserted().Count); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.pgsql.Insert(items).ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("id, 222"); + var dt3 = select.Limit(10).ToDataTable(a => new { id = a.Id, name2 = a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } + [Fact] + public void ToList() + { + + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + + var t1 = g.pgsql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); + var t2 = g.pgsql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql(); + + + var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToSql(); + var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToSql(); + var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToSql(); + + //g.pgsql.Select().Join((a, b, c) => new Model.JoinResult3( + // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, + // Model.JoinType.InnerJoin, c.Id == b.ParentId && c.Name == "xxx") + //); + + //var sql4 = select.From((a, b, c) => new SelectFrom() + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) + //.Where(a => a.Id == 1).ToSql(); + + var sql4 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name == "xxx")).ToSql(); + //.Where(a => a.Id == 1).ToSql(); + + + var list111 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name != "xxx")); + var list111sql = list111.ToSql(); + var list111data = list111.ToList((a, b, c) => new + { + a.Id, + title_substring = a.Title.Substring(0, 1), + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + }); + + var ttt122 = g.pgsql.Select().Where(a => a.Id > 0).ToSql(); + var sql5 = g.pgsql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToSql(); + var t11112 = g.pgsql.Select().ToList(a => new + { + a.Id, + a.Title, + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + + }); + + var t100 = g.pgsql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + var t101 = g.pgsql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + + + var t1111 = g.pgsql.Select().ToList(a => new { a.Id, a.Title, a.Type }); + + var t2222 = g.pgsql.Select().ToList(a => new { a.Id, a.Title, a.Type.Name }); + + g.pgsql.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.pgsql.Select().ToList(); + var testGuidId6 = g.pgsql.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.pgsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.pgsql.GetRepository(); + repo.DbContextOptions.EnableCascadeSave = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.pgsql.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Single(ddd); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Fact] + public void ToDictionary() + { + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.pgsql.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + + [Fact] + public void From() + { + + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\"", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\" LEFT JOIN \"testtypeparentinfo\" c ON b.\"parentid\" = c.\"id\"", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfo\" c ON c.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\" LEFT JOIN \"testtypeparentinfo\" c ON b.\"parentid\" = c.\"id\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" INNER JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" INNER JOIN \"testtypeparentinfo\" c ON c.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\" INNER JOIN \"testtypeparentinfo\" c ON b.\"parentid\" = c.\"id\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a INNER JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" RIGHT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" RIGHT JOIN \"testtypeparentinfo\" c ON c.\"id\" = a__Type.\"parentid\"", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b ON a.\"typeguid\" = b.\"guid\" RIGHT JOIN \"testtypeparentinfo\" c ON b.\"parentid\" = c.\"id\"", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\""); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a RIGHT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); + query.ToList(); + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������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\", a.\"clicks\", a.\"typeguid\", 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\", a.\"clicks\", a.\"typeguid\", 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\", a.\"clicks\", a.\"typeguid\", 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\", a.\"clicks\", a.\"typeguid\", 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.\"typeguid\" WHERE (a__Type.\"name\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" WHERE (a__Type.\"name\" = 'typeTitle' AND a__Type.\"guid\" = a.\"typeguid\")", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"name\" = 'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b WHERE (b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b WHERE (b.\"name\" = 'typeTitle' AND b.\"guid\" = a.\"typeguid\")", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeparentinfo\" c WHERE (c.\"name\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b, \"testtypeparentinfo\" c 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\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"clicks\" > 100 and a.\"id\" = @id)", sql); + query.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������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\", a.\"clicks\", a.\"typeguid\", 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\", a.\"clicks\", a.\"typeguid\", 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\", a.\"clicks\", a.\"typeguid\", 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\", a.\"clicks\", a.\"typeguid\", 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.\"typeguid\" WHERE (a__Type.\"name\" = 'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" WHERE (a__Type.\"name\" = 'typeTitle' AND a__Type.\"guid\" = a.\"typeguid\")", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a LEFT JOIN \"testtypeinfo\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfo\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"name\" = 'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .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\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b, \"testtypeparentinfo\" c 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\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a WHERE (a.\"clicks\" > 100 and a.\"id\" = @id)", sql); + query.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", 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\", a.\"clicks\", a.\"typeguid\", 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\", a.\"clicks\", a.\"typeguid\", 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\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", 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\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .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\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a, \"testtypeinfo\" b, \"testtypeparentinfo\" c", 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\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a", sql); + query.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .Count(out var trycount) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.pgsql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.pgsql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void OrderByRandom() + { + var t1 = select.OrderByRandom().Limit(10).ToSql("1"); + Assert.Equal(@"SELECT 1 +FROM ""tb_topic"" a +ORDER BY random() +limit 10", t1); + var t2 = select.OrderByRandom().Limit(10).ToList(); + } + + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).Limit(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + var subquery = select.ToSql(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, coalesce((SELECT sum(b.""id"") + FROM ""tb_topic"" b), 0) as6 +FROM ""tb_topic"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + } + [Fact] + public void Min() + { + var subquery = select.ToSql(a => new + { + all = a, + min = select.As("b").Min(b => b.Id), + min2 = select.As("b").Min(b => b.CreateTime) + }); + Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, coalesce((SELECT min(b.""id"") + FROM ""tb_topic"" b), 0) as6, coalesce((SELECT min(b.""createtime"") + FROM ""tb_topic"" b), '0001-01-01 00:00:00.000000') as7 +FROM ""tb_topic"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + min = select.As("b").Min(b => b.Id), + min2 = select.As("b").Min(b => b.CreateTime) + }); + } + [Fact] + public void Max() + { + var subquery = select.ToSql(a => new + { + all = a, + max = select.As("b").Max(b => b.Id), + max2 = select.As("b").Max(b => b.CreateTime) + }); + Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, coalesce((SELECT max(b.""id"") + FROM ""tb_topic"" b), 0) as6, coalesce((SELECT max(b.""createtime"") + FROM ""tb_topic"" b), '0001-01-01 00:00:00.000000') as7 +FROM ""tb_topic"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + max = select.As("b").Max(b => b.Id), + max2 = select.As("b").Max(b => b.CreateTime) + }); + } + [Fact] + public void Avg() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + Assert.Equal(@"SELECT a.""id"" as1, a.""clicks"" as2, a.""typeguid"" as3, a.""title"" as4, a.""createtime"" as5, coalesce((SELECT avg(b.""id"") + FROM ""tb_topic"" b), 0) as6 +FROM ""tb_topic"" a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + } + [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.""id"", a.""clicks"", a.""typeguid"", a.""title"", a.""createtime"" +FROM ""tb_topic"" a +WHERE ((((a.""id"")::text) in (SELECT b.""title"" + FROM ""tb_topic"" b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + + subquery = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.""id"", a.""clicks"", a.""typeguid"", a.""title"", a.""createtime"" +FROM ""tb_topic"" a +WHERE ((((a.""id"")::text) in (SELECT b.""title"" + FROM ""tb_topic"" b + limit 10)))", subquery); + subqueryList = select.Where(a => select.As("b").Limit(10).ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic where clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (type == typeof(Topic)) return oldname + "AsTable1"; + else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; + return oldname + "AsTable"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\"", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfoastable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" b ON b.\"guid\" = a.\"typeguid\"", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" b ON b.\"guid\" = a.\"typeguid\" AND b.\"name\" = 'xxx'", sql); + + query = select.LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid && a__Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" AND a__Type.\"name\" = 'xxx' LEFT JOIN \"testtypeparentinfoastable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\" WHERE (a__Type__Parent.\"id\" = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfoastable\" a__Type__Parent ON a__Type__Parent.\"id\" = a__Type.\"parentid\"", sql); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a__Type.\"guid\", a__Type.\"parentid\", a__Type.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" a__Type ON a__Type.\"guid\" = a.\"typeguid\" LEFT JOIN \"testtypeparentinfoastable\" c ON c.\"id\" = a__Type.\"parentid\"", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", b.\"guid\", b.\"parentid\", b.\"name\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfoastable2\" b ON a.\"typeguid\" = b.\"guid\" LEFT JOIN \"testtypeparentinfoastable\" c ON b.\"parentid\" = c.\"id\"", sql); + + //������϶����㲻�� + query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\"", sql); + + query = select.LeftJoin("\"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topicastable1\" a LEFT JOIN \"testtypeinfo\" b on b.\"guid\" = a.\"typeguid\" and b.\"name\" = @bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a) ftb UNION ALL SELECT * from (SELECT a.\"id\", a.\"clicks\", a.\"typeguid\", a.\"title\", a.\"createtime\" FROM \"tb_topic\" a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM \"tb_topic\" a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM \"tb_topic\" a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); + } + + public class TestInclude_OneToManyModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TestInclude_OneToManyModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TestInclude_OneToManyModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TestInclude_OneToManyModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TestInclude_OneToManyModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TestInclude_OneToManyModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.pgsql.Insert(model1).ExecuteIdentity(); + var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.pgsql.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.pgsql.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.pgsql.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.pgsql.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.pgsql.Insert(model4s).ExecuteAffrows()); + + var t0 = g.pgsql.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.pgsql.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + //---- Select ---- + + var at0 = g.pgsql.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.pgsql.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.pgsql.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TestInclude_OneToManyModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TestInclude_OneToManyModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TestInclude_OneToManyModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } + public List childs { get; set; } + } + public class TestInclude_OneToManyModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; + model2.id = (int)g.pgsql.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.pgsql.Insert(model3s).ExecuteAffrows()); + + var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.pgsql.Insert(model1).ExecuteIdentity(); + + var t1 = g.pgsql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.pgsql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + //---- Select ---- + + var at1 = g.pgsql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.pgsql.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.pgsql.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.pgsql.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.pgsql.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.pgsql.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.pgsql.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.pgsql.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.pgsql.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.pgsql.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.pgsql.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.pgsql.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + // --- Select --- + + var atags0 = g.pgsql.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.pgsql.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.pgsql.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.pgsql.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.pgsql.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.pgsql.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.pgsql.Insert(song3).ExecuteIdentity(); + + g.pgsql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.pgsql.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.pgsql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.pgsql.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.pgsql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.pgsql.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.pgsql.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.pgsql.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.pgsql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.pgsql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.pgsql, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.pgsql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.pgsql.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.pgsql.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.pgsql.Select().Count()); + Assert.Equal(3, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.pgsql.Select().Count()); + Assert.Equal(3, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.pgsql.Select().Count()); + Assert.Equal(3, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.pgsql.Select().Count()); + Assert.Equal(5, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.pgsql.Select().Count()); + Assert.Equal(5, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.pgsql.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.pgsql.Select().Count()); + g.pgsql.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.pgsql.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.pgsql.Select().Count()); + Assert.Equal(5, g.pgsql.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + [Fact] + public void ForUpdate() + { + var orm = g.pgsql; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"name\" FROM \"toupd1pk\" a limit 1 for update", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.\"id\", a.\"name\" FROM \"toupd1pk\" a limit 1 for update nowait", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } + + [Fact] + public void ToTreeList() + { + var fsql = g.pgsql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableCascadeSave = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); + Assert.Equal(4, t3.Count); + Assert.Equal("100000", t3[0].Code); + Assert.Equal("110000", t3[1].Code); + Assert.Equal("110100", t3[2].Code); + Assert.Equal("110101", t3[3].Code); + + t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); + Assert.Equal(3, t3.Count); + Assert.Equal("110000", t3[0].Code); + Assert.Equal("110100", t3[1].Code); + Assert.Equal("110101", t3[2].Code); + + var t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name).OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国", t4[0].path); + Assert.Equal("中国 -> 北京", t4[1].path); + Assert.Equal("中国 -> 北京 -> 北京市", t4[2].path); + Assert.Equal("中国 -> 北京 -> 东城区", t4[3].path); + + t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name + "[" + a.Code + "]").OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国[100000]", t4[0].path); + Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); + + var select = fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte() + //.OrderBy("a.cte_level desc") //递归层级 + ; + // var list = select.ToList(); //自己调试看查到的数据 + select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + Assert.Equal(855, fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Distinct().First(a => a.testint)); + + Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + Assert.False(fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Any()); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + + public int testint { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLUpdateTest.cs new file mode 100644 index 00000000..96e58b3b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/Curd/PostgreSQLUpdateTest.cs @@ -0,0 +1,185 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQL +{ + public class PostgreSQLUpdateTest + { + IUpdate update => g.pgsql.Update(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.pgsql.Update().ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test' \r\nWHERE (\"id\" IN (1,2))", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" IN (1,2))", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE \"tb_topic\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } + + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = NULL, \"title\" = 'newtitle', \"createtime\" = '0001-01-01 00:00:00.000000' WHERE (\"id\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; + + sql = update.SetSource(items).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = CASE \"id\" WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END::int4, \"title\" = CASE \"id\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END::text, \"createtime\" = CASE \"id\" WHEN 1 THEN '0001-01-01 00:00:00.000000' WHEN 2 THEN '0001-01-01 00:00:00.000000' WHEN 3 THEN '0001-01-01 00:00:00.000000' WHEN 4 THEN '0001-01-01 00:00:00.000000' WHEN 5 THEN '0001-01-01 00:00:00.000000' WHEN 6 THEN '0001-01-01 00:00:00.000000' WHEN 7 THEN '0001-01-01 00:00:00.000000' WHEN 8 THEN '0001-01-01 00:00:00.000000' WHEN 9 THEN '0001-01-01 00:00:00.000000' WHEN 10 THEN '0001-01-01 00:00:00.000000' END::timestamp WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = CASE \"id\" WHEN 1 THEN 'newtitle0' WHEN 2 THEN 'newtitle1' WHEN 3 THEN 'newtitle2' WHEN 4 THEN 'newtitle3' WHEN 5 THEN 'newtitle4' WHEN 6 THEN 'newtitle5' WHEN 7 THEN 'newtitle6' WHEN 8 THEN 'newtitle7' WHEN 9 THEN 'newtitle8' WHEN 10 THEN 'newtitle9' END::text WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"createtime\" = '2020-01-01 00:00:00.000000' WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.pgsql.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } + } + [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE \"tssi01\" SET \"tint\" = 10 WHERE (\"id\" = '00000000-0000-0000-0000-000000000000')", + g.pgsql.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = 'newtitle' WHERE (\"id\" = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = 'newtitle' WHERE (\"id\" = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = 'newtitle' WHERE (\"id\" = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"title\" = 'newtitle', \"createtime\" = '2020-01-01 00:00:00.000000' WHERE (\"id\" = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = coalesce(\"clicks\", 0) * 10 / 1 WHERE (\"id\" = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"id\" = (\"id\" - 10) WHERE (\"id\" = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = coalesce(\"clicks\", 0) * 10 / 1 WHERE (\"id\" = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"id\" = (\"id\" - 10) WHERE (\"id\" = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = \"clicks\" * 10 / 1 WHERE (\"id\" = 1)", sql); + + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = case when \"createtime\" > '2000-01-01 00:00:00.000000' then 1 else 2 end WHERE (\"id\" = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"id\" = 10 WHERE (\"id\" = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = NULL WHERE (\"id\" = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + ?", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET clicks = clicks + ? WHERE (\"id\" = 1)", sql); + } + [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = 1, \"title\" = 'xxx' WHERE (\"id\" = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET \"clicks\" = 1, \"title\" = 'xxx' WHERE (\"id\" = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"id\" = 1)", sql); + + sql = update.Where("id = ?", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (id = ?)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"id\" = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE \"tb_topic\" SET title='newtitle' WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + update.SetSource(items.First()).NoneParameter().ExecuteAffrows(); + update.SetSource(items).NoneParameter().ExecuteAffrows(); + } + [Fact] + public void ExecuteUpdated() + { + + } + + [Fact] + public void AsTable() + { + Assert.Null(g.pgsql.Update().ToSql()); + Assert.Equal("UPDATE \"tb_topicastable\" SET title='test' \r\nWHERE (\"id\" IN (1,2))", g.pgsql.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicastable\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicastable\" SET title='test1' \r\nWHERE (\"id\" IN (1,2))", g.pgsql.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE \"tb_topicastable\" SET title='test1' \r\nWHERE (\"id\" = 1)", g.pgsql.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..5dfedace --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/BoolNullableTest.cs @@ -0,0 +1,1571 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQLMapType +{ + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.pgsql; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/BoolTest.cs new file mode 100644 index 00000000..8feba9bf --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/BoolTest.cs @@ -0,0 +1,1105 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQLMapType +{ + public class BoolTest + { + + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.pgsql; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..5f98b168 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQLMapType +{ + public class DateTimeOffSetTest + { + class DateTimeOffSetTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtosnullable_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.pgsql; + var item = new DateTimeOffSetTestMap { dtos_to_dt = DateTimeOffset.Now, dtosnullable_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/EnumTest.cs new file mode 100644 index 00000000..96b58123 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/EnumTest.cs @@ -0,0 +1,261 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQLMapType +{ + public class EnumTest + { + class EnumTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.pgsql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.pgsql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() + { + //insert + var orm = g.pgsql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.pgsql; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/ToStringTest.cs new file mode 100644 index 00000000..e8a5e39f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/MapType/ToStringTest.cs @@ -0,0 +1,570 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQLMapType +{ + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.pgsql; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs new file mode 100644 index 00000000..7c615389 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs @@ -0,0 +1,75 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQL +{ + public class PostgreSQLAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.pgsql.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() + { + var t2 = g.pgsql.Ado.SlavePools.Count; + } + + [Fact] + public void ExecuteTest() + { + Assert.True(g.pgsql.Ado.ExecuteConnectTest()); + } + [Fact] + public void ExecuteReader() + { + + } + [Fact] + public void ExecuteArray() + { + + } + [Fact] + public void ExecuteNonQuery() + { + + } + [Fact] + public void ExecuteScalar() + { + + } + + [Fact] + public void Query() + { + + g.pgsql.CodeFirst.SyncStructure(); + var t3 = g.pgsql.Ado.Query("select * from xxx"); + + var t4 = g.pgsql.Ado.Query<(int, string, string)>("select * from xxx"); + + var t5 = g.pgsql.Ado.Query("select * from xxx"); + } + + [Fact] + public void QueryMultipline() + { + g.pgsql.CodeFirst.SyncStructure(); + var t3 = g.pgsql.Ado.Query("select * from xxx; select * from xxx; select * from xxx"); + } + + class xxx + { + public string Id { get; set; } + public string Path { get; set; } + public string Title2 { get; set; } + + public string testf { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLAopTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLAopTest.cs new file mode 100644 index 00000000..a31d5de1 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQL +{ + public class PostgreSQLAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var date = DateTime.Now.Date; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now.Date; + }; + g.pgsql.Aop.AuditValue += audit; + + g.pgsql.Insert(item).ExecuteAffrows(); + + g.pgsql.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime, date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLCodeFirstTest.cs new file mode 100644 index 00000000..d87ef8c1 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLCodeFirstTest.cs @@ -0,0 +1,287 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQL +{ + public class PostgreSQLCodeFirstTest + { + [Fact] + public void Test_0String() + { + var fsql = g.pgsql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + + Assert.Equal(1, fsql.Insert(new test_0string01 { name = @"1.0000\0.0000\0.0000\0.0000\1.0000\0.0000" }).ExecuteAffrows()); + Assert.Equal(1, fsql.Insert(new test_0string01 { name = @"1.0000\0.0000\0.0000\0.0000\1.0000\0.0000" }).NoneParameter().ExecuteAffrows()); + + var list = fsql.Select().ToList(); + Assert.Equal(2, list.Count); + Assert.Equal(@"1.0000\0.0000\0.0000\0.0000\1.0000\0.0000", list[0].name); + Assert.Equal(@"1.0000\0.0000\0.0000\0.0000\1.0000\0.0000", list[1].name); + } + class test_0string01 + { + public Guid id { get; set; } + public string name { get; set; } + } + + [Fact] + public void StringLength() + { + var dll = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + g.pgsql.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } + } + + [Fact] + public void 中文表_字段() + { + var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements<测试中文表>(); + g.pgsql.CodeFirst.SyncStructure<测试中文表>(); + + var item = new 测试中文表 + { + 标题 = "测试标题", + 创建时间 = DateTime.Now + }; + Assert.Equal(1, g.pgsql.Insert<测试中文表>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.编号); + var item2 = g.pgsql.Select<测试中文表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新"; + Assert.Equal(1, g.pgsql.Update<测试中文表>().SetSource(item).ExecuteAffrows()); + item2 = g.pgsql.Select<测试中文表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新_repo"; + var repo = g.pgsql.GetRepository<测试中文表>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.pgsql.Select<测试中文表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.pgsql.Select<测试中文表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + } + class 测试中文表 + { + [Column(IsPrimary = true)] + public Guid 编号 { get; set; } + + public string 标题 { get; set; } + + public DateTime 创建时间 { get; set; } + } + + [Fact] + public void AddUniques() + { + var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + g.pgsql.CodeFirst.SyncStructure(); + g.pgsql.CodeFirst.SyncStructure(typeof(AddUniquesInfo), "AddUniquesInfo1"); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("{tablename}_uk_phone", "phone", true)] + [Index("{tablename}_uk_group_index", "group,index", true)] + [Index("{tablename}_uk_group_index22", "group, index22", true)] + class AddUniquesInfo + { + public Guid id { get; set; } + public string phone { get; set; } + + public string group { get; set; } + public int index { get; set; } + public string index22 { get; set; } + } + + [Fact] + public void AddField() + { + var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + Assert.True(string.IsNullOrEmpty(sql)); //测试运行两次后 + g.pgsql.Select(); + var id = g.pgsql.Insert().AppendData(new TopicAddField { }).ExecuteIdentity(); + } + + [Table(Name = "ccc.TopicAddField", OldName = "TopicAddField")] + public class TopicAddField + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public string name { get; set; } = "xxx"; + + public int clicks { get; set; } = 10; + //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"; + + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() + { + + var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements(); + g.pgsql.Select(); + } + + IInsert insert => g.pgsql.Insert(); + ISelect select => g.pgsql.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + testFieldBool = true, + testFieldBoolNullable = true, + testFieldByte = byte.MaxValue, + testFieldByteNullable = byte.MinValue, + testFieldBytes = Encoding.UTF8.GetBytes("我是中国人"), + testFieldDateTime = DateTime.Now, + testFieldDateTimeNullable = DateTime.Now.AddDays(-1), + testFieldDecimal = 999.99M, + testFieldDecimalNullable = 111.11M, + testFieldDouble = 888.88, + testFieldDoubleNullable = 222.22, + testFieldEnum1 = TableAllTypeEnumType1.e3, + testFieldEnum1Nullable = TableAllTypeEnumType1.e2, + testFieldEnum2 = TableAllTypeEnumType2.f2, + testFieldEnum2Nullable = TableAllTypeEnumType2.f3, + testFieldFloat = 777.77F, + testFieldFloatNullable = 333.33F, + testFieldGuid = Guid.NewGuid(), + testFieldGuidNullable = Guid.NewGuid(), + testFieldInt = int.MaxValue, + testFieldIntNullable = 123, + testFieldLong = long.MaxValue, + + testFieldSByte = sbyte.MaxValue, + testFieldSByteNullable = sbyte.MinValue, + testFieldShort = short.MaxValue, + testFieldShortNullable = short.MinValue, + testFieldString = "我是中国人string'\\?!@#$%^&*()_+{}}{~?><<>", + testFieldChar = 'X', + testFieldTimeSpan = TimeSpan.FromDays(1), + testFieldTimeSpanNullable = TimeSpan.FromSeconds(90), + testFieldUInt = uint.MaxValue, + testFieldUIntNullable = uint.MinValue, + testFieldULong = ulong.MaxValue, + testFieldULongNullable = ulong.MinValue, + testFieldUShort = ushort.MaxValue, + testFieldUShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue, + }; + + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteInserted(); + + var item3 = insert.AppendData(item2).ExecuteInserted().First(); + var newitem2 = select.Where(a => a.Id == item3.Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); + + item3 = insert.NoneParameter().AppendData(item2).ExecuteInserted().First(); + newitem2 = select.Where(a => a.Id == item3.Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); + + var items = select.ToList(); + var itemstb = select.ToDataTable(); + } + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + 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 byte[] testFieldBytes { get; set; } + public string testFieldString { get; set; } + public char testFieldChar { 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 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/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLDbFirstTest.cs new file mode 100644 index 00000000..642732aa --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLDbFirstTest.cs @@ -0,0 +1,65 @@ +using FreeSql.DataAnnotations; +using System; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQL +{ + public class PostgreSQLDbFirstTest + { + [Fact] + public void GetDatabases() + { + var t1 = g.pgsql.DbFirst.GetDatabases(); + } + + [Fact] + public void GetTablesByDatabase() + { + var t2 = g.pgsql.DbFirst.GetTablesByDatabase(); + Assert.True(t2.Count > 0); + } + + [Fact] + public void GetTableByName() + { + var fsql = g.pgsql; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("public.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); + } + + [Fact] + public void ExistsTable() + { + var fsql = g.pgsql; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("public.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("public.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("public.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("Test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("public.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("tbexts.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("tbexts.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "tbexts.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("tbexts.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("tbexts.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table \"tbexts\".test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/ConvertTest.cs new file mode 100644 index 00000000..cf2aa4bf --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/ConvertTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQLExpression +{ + public class ConvertTest + { + + ISelect select => g.pgsql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() + { + var data = new List(); + data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + //data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + //data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.Empty.ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + //data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs new file mode 100644 index 00000000..2049466d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/DateTimeTest.cs @@ -0,0 +1,732 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQLExpression +{ + public class DateTimeTest + { + + ISelect select => g.pgsql.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInfo23123")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') = now())) + + g.pgsql.Insert(new Topic()).ExecuteAffrows(); + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t").Replace("", "AM").Replace("", "PM").Replace("", "A").Replace("", "P"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t"))); + } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(utc_timestamp(), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('0001/1/1 0:00:00' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(cast('9999/12/31 23:59:59' as datetime), '%Y-%m-%d') as datetime)) + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime) = cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime) > cast(date_format(now(), '%Y-%m-%d') as datetime)); + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((timestampdiff(microsecond, cast(date_format(a.`CreateTime`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type.`Time`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((timestampdiff(microsecond, cast(date_format(a__Type__Parent.`Time2`, '%Y-%m-%d') as datetime), now())) / 1000000) > 0) + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, date_format(a__Type.`Time`, '1970-1-1 %H:%i:%s.%f'), a__Type.`Time`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, date_format(a__Type__Parent.`Time2`, '1970-1-1 %H:%i:%s.%f'), a__Type__Parent.`Time2`) + 62135596800000000) > (timestampdiff(microsecond, date_format(now(), '1970-1-1 %H:%i:%s.%f'), now()) + 62135596800000000)) + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((dayofweek(a.`CreateTime`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((dayofweek(a__Type.`Time`) - 1) > (dayofweek(now()) - 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((dayofweek(a__Type__Parent.`Time2`) - 1) > (dayofweek(now()) - 1)) + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(a.`CreateTime`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(a__Type.`Time`) > dayofmonth(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(a__Type__Parent.`Time2`) > dayofmonth(now())) + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofyear(a.`CreateTime`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofyear(a__Type.`Time`) > dayofyear(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofyear(a__Type__Parent.`Time2`) > dayofyear(now())) + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (month(a.`CreateTime`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (month(a__Type.`Time`) > month(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (month(a__Type__Parent.`Time2`) > month(now())) + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (year(a.`CreateTime`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (year(a__Type.`Time`) > year(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (year(a__Type__Parent.`Time2`) > year(now())) + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (hour(a.`CreateTime`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (hour(a__Type.`Time`) > hour(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (hour(a__Type__Parent.`Time2`) > hour(now())) + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (minute(a.`CreateTime`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (minute(a__Type.`Time`) > minute(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (minute(a__Type__Parent.`Time2`) > minute(now())) + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (second(a.`CreateTime`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (second(a__Type.`Time`) > second(now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (second(a__Type__Parent.`Time2`) > second(now())) + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (floor(microsecond(a.`CreateTime`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (floor(microsecond(a__Type.`Time`) / 1000) > floor(microsecond(now()) / 1000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (floor(microsecond(a__Type__Parent.`Time2`) / 1000) > floor(microsecond(now()) / 1000)) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((timestampdiff(microsecond, '1970-1-1', a.`CreateTime`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type.`Time`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((timestampdiff(microsecond, '1970-1-1', a__Type__Parent.`Time2`) * 10 + 621355968000000000) > (timestampdiff(microsecond, '1970-1-1', now()) * 10 + 621355968000000000)) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval ((1 * 86400000000)) microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval ((1 * 86400000000)) microsecond) > now()) + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) day) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) day) > now()) + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) hour) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) hour) > now()) + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) * 1000 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) * 1000 microsecond) > now()) + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) minute) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) minute) > now()) + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) month) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) month) > now()) + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) second) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) second) > now()) + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) / 10 microsecond) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) / 10 microsecond) > now()) + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (date_add(a.`CreateTime`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (date_add(a__Type.`Time`, interval (1) year) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (date_add(a__Type__Parent.`Time2`, interval (1) year) > now()) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" + //FROM "tb_topic111333" a + //WHERE ((((extract(epoch from (a."createtime")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //WHERE ((((extract(epoch from (a__Type."time")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" + //WHERE ((((extract(epoch from (a__Type__Parent."time2")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" + //FROM "tb_topic111333" a + //WHERE (((a."createtime")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //WHERE (((a__Type."time")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" + //WHERE (((a__Type__Parent."time2")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" + //FROM "tb_topic111333" a + //WHERE ((((extract(epoch from (a."createtime")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //WHERE ((((extract(epoch from (a__Type."time")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" + //WHERE ((((extract(epoch from (a__Type__Parent."time2")::timestamp-(current_timestamp)::timestamp)*1000000))/1000000) > 0) + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + //SELECT a."id", a."clicks", a."typeguid", a."title", a."createtime" + //FROM "tb_topic111333" a + //WHERE (((a."createtime")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //WHERE (((a__Type."time")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + + //SELECT a."id", a."clicks", a."typeguid", a__Type."guid", a__Type."parentid", a__Type."name", a__Type."time", a."title", a."createtime" + //FROM "tb_topic111333" a + //LEFT JOIN "testtypeinfo333" a__Type ON a__Type."guid" = a."typeguid" + //LEFT JOIN "testtypeparentinfo23123" a__Type__Parent ON a__Type__Parent."id" = a__Type."parentid" + //WHERE (((a__Type__Parent."time2")::timestamp-((((1)*86400000000))||' microseconds')::interval) > a."createtime") + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((a.`CreateTime`) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((date_add(a__Type.`Time`, interval (1) year)) - (now())) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((date_add(a__Type__Parent.`Time2`, interval (1) year)) - (now())) = 0) + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (dayofmonth(last_day(concat(year(a.`CreateTime`), month(a.`CreateTime`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (dayofmonth(last_day(concat(year(a__Type.`Time`), month(a__Type.`Time`), '-01'))) > 30); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (dayofmonth(last_day(concat(year(a__Type__Parent.`Time2`), month(a__Type__Parent.`Time2`), '-01'))) > 30) + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE ((date_add(a.`CreateTime`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE ((date_add(a__Type.`Time`, interval (1) year) = now())); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE ((date_add(a__Type__Parent.`Time2`, interval (1) year) = now())) + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (((year(a.`CreateTime`)) % 4 = 0 AND (year(a.`CreateTime`)) % 100 <> 0 OR (year(a.`CreateTime`)) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (((year(date_add(a__Type.`Time`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type.`Time`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type.`Time`, interval (1) year))) % 400 = 0)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (((year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 4 = 0 AND (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 100 <> 0 OR (year(date_add(a__Type__Parent.`Time2`, interval (1) year))) % 400 = 0)) + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic111333` a + //WHERE (cast(date_format(a.`CreateTime`, '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type + //WHERE (cast(date_format(date_add(a__Type.`Time`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a__Type.`Guid` as4, a__Type.`ParentId` as5, a__Type.`Name` as6, a__Type.`Time` as7, a.`Title` as8, a.`CreateTime` as9 + //FROM `tb_topic111333` a, `TestTypeInfo333` a__Type, `TestTypeParentInfo23123` a__Type__Parent + //WHERE (cast(date_format(date_add(a__Type__Parent.`Time2`, interval (1) year), '%Y-%m-%d %H:%i:%s.%f') as datetime) > now()) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/MathTest.cs new file mode 100644 index 00000000..14e318aa --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/MathTest.cs @@ -0,0 +1,156 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQLExpression +{ + public class MathTest + { + + ISelect select => g.pgsql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + var data = new List(); + //data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + var data = new List(); + //data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/OtherTest.cs new file mode 100644 index 00000000..76b17b9b --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/OtherTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json.Linq; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQLExpression +{ + public class OtherTest + { + + ISelect select => g.pgsql.Select(); + + public OtherTest() + { + } + + [Fact] + public void Div() + { + var t1 = select.Where(a => a.testFieldInt / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.testFieldLong / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.testFieldShort / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.testFieldInt / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.testFieldLong / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.testFieldShort / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.testFieldDouble / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.testFieldDecimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.testFieldFloat / 3 > 3).Limit(10).ToList(); + } + + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.testFieldBool == true).ToList(); + var t2 = select.Where(a => a.testFieldBool != true).ToList(); + var t3 = select.Where(a => a.testFieldBool == false).ToList(); + var t4 = select.Where(a => !a.testFieldBool).ToList(); + var t5 = select.Where(a => a.testFieldBool).ToList(); + var t51 = select.WhereCascade(a => a.testFieldBool).Limit(10).ToList(); + + var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); + var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); + var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); + var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); + var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.testFieldBool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.testFieldBool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.testFieldBool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.testFieldBool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.testFieldBool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.testFieldBool == true && a.Id > 0 && a.testFieldBool == true).ToList(); + var t22222 = select.Where(a => a.testFieldBool != true && a.Id > 0 && a.testFieldBool != true).ToList(); + var t33333 = select.Where(a => a.testFieldBool == false && a.Id > 0 && a.testFieldBool == false).ToList(); + var t44444 = select.Where(a => !a.testFieldBool && a.Id > 0 && !a.testFieldBool).ToList(); + var t55555 = select.Where(a => a.testFieldBool && a.Id > 0 && a.testFieldBool).ToList(); + + var t111111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0 && a.testFieldBoolNullable == true).ToList(); + var t222222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0 && a.testFieldBoolNullable != true).ToList(); + var t333333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0 && a.testFieldBoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0 && !a.testFieldBoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0 && a.testFieldBoolNullable.Value).ToList(); + } + + [Fact] + public void Array() + { + //g.pgsql.Aop.CurdAfter = (s, e) => { + // Trace.WriteLine(e.CurdType + ": " + e.ElapsedMilliseconds + "ms " + e.Sql.Replace("\n", "")); + //}; + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToSql(); + var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToSql(); + var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToSql(); + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.testFieldInt)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.testFieldInt) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.testFieldInt)).ToList(); + } + + + [Table(Name = "tb_alltype")] + class TableAllType + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + + 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 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 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/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/StringTest.cs new file mode 100644 index 00000000..3976ac96 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -0,0 +1,829 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQLExpression +{ + public class StringTest + { + + ISelect select => g.pgsql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.pgsql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + [Fact] + public void StringJoin() + { + var fsql = g.pgsql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + + [Fact] + public void Format() + { + var item = g.pgsql.GetRepository().Insert(new Topic { Clicks = 101, Title = "我是中国人101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT 'x'||coalesce(((a.""id"" + 1))::text, '')||'z-'||coalesce(to_char((a.""createtime"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""title"", '')||'' as1, ''||coalesce(((a.""id"" + 1))::text, '')||'x'||coalesce(((a.""id"" + 1))::text, '')||'z-'||coalesce(to_char((a.""createtime"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""title"", '')||'' as2 +FROM ""tb_topic"" a +WHERE (a.""id"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + + [Fact] + public void Format4() + { + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var item = g.pgsql.GetRepository().Insert(new Topic { Clicks = 101, Title = "我是中国人101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT 'x'||coalesce(((a.""id"" + 1))::text, '')||'z-'||coalesce(to_char((a.""createtime"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""title"", '')||''||coalesce(a.""title"", '')||'' as1, ''||coalesce(((a.""id"" + 1))::text, '')||'x'||coalesce(((a.""id"" + 1))::text, '')||'z-'||coalesce(to_char((a.""createtime"")::timestamp,'YYYYMM'), '')||''||coalesce(a.""title"", '')||''||coalesce(a.""title"", '')||'' as2 +FROM ""tb_topic"" a +WHERE (a.""id"" = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ifnull(a.`Title`, '') = '') + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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.`Title`) LIKE concat('%', a__Type.`Name`)) + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`)) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1))) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`)) + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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.`Title`) LIKE concat(a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE 'aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat(concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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((concat(a.`Title`, 'aaa')) LIKE concat(a__Type.`Name`, '%')) + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((a.`Title`) LIKE concat('%', a.`Title` +1, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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.`Title`) LIKE concat('%', a__Type.`Name`, '%')) + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE '%aaa%') + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', a.`Title`, '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE((concat(a.`Title`, 'aaa')) LIKE concat('%', concat(a.`Title`, 1), '%')) + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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((concat(a.`Title`, 'aaa')) LIKE concat('%', a__Type.`Name`, '%')) + + + list.Add(select.Where(a => a.Title.Contains("%")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + "%")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1 + "%")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name + "%")).ToList()); + + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa" + "%")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + "%")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1 + "%")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name + "%")).ToList()); + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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(lower(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE(lower(concat(lower(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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(lower(concat(lower(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(a.`Title`) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (upper(a.`Title`) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (upper(concat(upper(a.`Title`), 'aaa')) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (upper(concat(upper(a.`Title`), 'aaa')) = a__Type.`Name`) + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(a.`Title`, 1) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (substr(a.`Title`, 1) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), char_length(a.`Title`) + 1) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, char_length(a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (substr(concat(substr(a.`Title`, 1), 'aaa'), 1, 3) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (substr(concat(substr(a.`Title`, 1), 'aaa'), 2, 2) = a__Type.`Name`) + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(a.`Title`) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (char_length(a.`Title`) = char_length(a__Type.`Name`)); + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (char_length(concat(a.`Title`, 'aaa')) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (char_length(concat(a.`Title`, 'aaa')) = char_length(a__Type.`Name`)) + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 ((locate(a.`Title`, 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa') - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = -1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a.`Title`) + 1); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 ((locate(concat(a.`Title`, 'aaa'), 'aaa', 3) - 1) = char_length(a__Type.`Name`) + 1) + } + [Fact] + public void PadLeft() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (lpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (lpad(concat(lpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void PadRight() + { + var data = new List(); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(a.`Title`, 10, 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (rpad(a.`Title`, 10, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (rpad(concat(rpad(a.`Title`, 10, 'a'), 'aaa'), 20, 'b') = a__Type.`Name`) + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim('c' from trim('b' from trim('a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(concat(trim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('a' from concat(trim('a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim('b' from trim('a' from concat(trim('b' from trim('a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim('c' from trim('b' from trim('a' from concat(trim('c' from trim('b' from trim('a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from a.`Title`)) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (ltrim(concat(ltrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'a' from trim(leading 'a' from a.`Title`)), 'aaa'))) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))), 'aaa'))))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from concat(trim(trailing 'c' from trim(leading 'c' from trim(trailing 'b' from trim(leading 'b' from trim(trailing 'a' from trim(leading 'a' from a.`Title`)))))), 'aaa'))))))) = a__Type.`Name`) + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(a.`Title`) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from a.`Title`) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from a.`Title`)) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))) = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (rtrim(concat(rtrim(a.`Title`), 'aaa')) = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'a' from concat(trim(trailing 'a' from a.`Title`), 'aaa')) = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'b' from trim(trailing 'a' from a.`Title`)), 'aaa'))) = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from concat(trim(trailing 'c' from trim(trailing 'b' from trim(trailing 'a' from a.`Title`))), 'aaa')))) = a__Type.`Name`) + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(a.`Title`, 'a', 'b') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(a.`Title`, 'a', 'b'), 'b', 'c') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a') = a__Type.`Name`); + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(a.`Title`, 'a', 'b'), 'aaa') = 'aaa'); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'aaa') = a.`Title`); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), 'c', 'a'), 'aaa') = concat(a.`Title`, 1)); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (concat(replace(replace(replace(a.`Title`, 'a', 'b'), 'b', 'c'), a__Type.`Name`, 'a'), 'aaa') = a__Type.`Name`) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(a.`Title`, concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (strcmp(a.`Title`, concat(a.`Title`, a__Type.`Name`)) = 0); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), 'aaa') = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), a.`Title`) > 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (strcmp(concat(a.`Title`, 'aaa'), concat(a.`Title`, 1)) = 0); + + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` 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 (strcmp(concat(a.`Title`, 'aaa'), a__Type.`Name`) = 0) + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs new file mode 100644 index 00000000..20538195 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/PostgreSQL/PostgreSQLExpression/TimeSpanTest.cs @@ -0,0 +1,293 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.PostgreSQLExpression +{ + public class TimeSpanTest + { + + ISelect select => g.pgsql.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > 0) + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) > -922337203685477580) + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) < 922337203685477580) + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 86400000000) = 0) + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 3600000000) mod 24 > 0) + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000 mod 1000) > 0) + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 60000000 mod 60) > 0) + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) div 1000000 mod 60) > 0) + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) * 10) > 0) + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 86400000000) > 0) + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 3600000000) > 0) + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000) > 0) + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 60000000) > 0) + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) / 1000000) > 0) + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) + (1 * 86400000000)) > 0) + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) - (1 * 86400000000)) > 0) + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') = 'ssss') + } + + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) - ((1 * 86400000000))) > 0) + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 86400000000))) + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 3600000000))) + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000))) + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 60000000))) + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 * 1000000))) + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE ((timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000) = (1 / 10))) + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + //data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + //SELECT a.`Id` as1, a.`Clicks` as2, a.`TypeGuid` as3, a.`Title` as4, a.`CreateTime` as5 + //FROM `tb_topic` a + //WHERE (cast(date_format(date_add(cast('0001/1/1 0:00:00' as datetime), interval (timestampdiff(microsecond, date_format(a.`CreateTime`, '1970-1-1 %H:%i:%s.%f'), a.`CreateTime`) + 62135596800000000)) microsecond), '%Y-%m-%d %H:%i:%s.%f') as signed) > 0) + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerDeleteTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerDeleteTest.cs new file mode 100644 index 00000000..3718b92a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerDeleteTest.cs @@ -0,0 +1,112 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServer +{ + [Collection("SqlServerCollection")] + public class SqlServerDeleteTest + { + IDelete delete => g.sqlserver.Delete(); //�������� + + [Table(Name = "tb_topic22211")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.sqlserver.Delete().ToSql()); + var sql = g.sqlserver.Delete(new[] { 1, 2 }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2))", sql); + + sql = g.sqlserver.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + + sql = g.sqlserver.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2))", sql); + + sql = g.sqlserver.Delete(new { id = 1 }).ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + + sql = g.sqlserver.Delete(new[] { new { Id1 = 1, Id2 = 10 }, new { Id1 = 2, Id2 = 20 } }).ToSql(); + Assert.Equal("DELETE FROM [MultiPkTopic] WHERE ([Id1] = 1 AND [Id2] = 10 OR [Id1] = 2 AND [Id2] = 20)", sql); + } + class MultiPkTopic + { + [Column(IsPrimary = true)] + public int Id1 { get; set; } + [Column(IsPrimary = true)] + public int Id2 { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Where() + { + var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + + sql = delete.Where("id = @id", new { id = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE (id = @id)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = delete.Where(item).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + sql = delete.Where(items).ToSql().Replace("\r\n", ""); + Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + + var id = g.sqlserver.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); + Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); + } + [Fact] + public void ExecuteDeleted() + { + + var item = g.sqlserver.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); + Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); + + var items = Enumerable.Range(0, 301).Select(a => new Topic { Title = "xxxx" + a, CreateTime = DateTime.Now }).ToArray(); + var itemsInserted = g.sqlserver.Insert(items).ExecuteInserted(); + Assert.Equal(items.First().Title, itemsInserted[0].Title); + + Assert.Equal(itemsInserted[0].Id, delete.Where(a => a.Id == itemsInserted[0].Id).ExecuteDeleted()[0].Id); + } + + [Fact] + public void AsTable() + { + Assert.Null(g.sqlserver.Delete().ToSql()); + var sql = g.sqlserver.Delete(new[] { 1, 2 }).AsTable(a => "tb_topic22211AsTable").ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] IN (1,2))", sql); + + sql = g.sqlserver.Delete(new Topic { Id = 1, Title = "test" }).AsTable(a => "tb_topic22211AsTable").ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); + + sql = g.sqlserver.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).AsTable(a => "tb_topic22211AsTable").ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] IN (1,2))", sql); + + sql = g.sqlserver.Delete(new { id = 1 }).AsTable(a => "tb_topic22211AsTable").ToSql(); + Assert.Equal("DELETE FROM [tb_topic22211AsTable] WHERE ([Id] = 1)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs new file mode 100644 index 00000000..7834ec30 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerInsertOrUpdateIfExistsDoNothingTest.cs @@ -0,0 +1,422 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServer +{ + public class SqlServerInsertOrUpdateIfExistsDoNothingTest + { + IFreeSql fsql => g.sqlserver; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as [id] ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.[id]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as [id] ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.[id]);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 2 as [id] ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.[id]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as [id] +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.[id]);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb01 { id = 1 }, new tbioudb01 { id = 2 }, new tbioudb01 { id = 3 }, new tbioudb01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb01] t1 +USING (SELECT 1 as [id] +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.[id]);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbioudb01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as [id], N'01' as [name] ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as [id], N'011' as [name] ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 2 as [id], N'02' as [name] ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "01" }, new tbioudb02 { id = 2, name = "02" }, new tbioudb02 { id = 3, name = "03" }, new tbioudb02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as [id], N'01' as [name] +UNION ALL + SELECT 2, N'02' +UNION ALL + SELECT 3, N'03' +UNION ALL + SELECT 4, N'04' ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb02 { id = 1, name = "001" }, new tbioudb02 { id = 2, name = "002" }, new tbioudb02 { id = 3, name = "003" }, new tbioudb02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb02] t1 +USING (SELECT 1 as [id], N'001' as [name] +UNION ALL + SELECT 2, N'002' +UNION ALL + SELECT 3, N'003' +UNION ALL + SELECT 4, N'004' ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as [id], N'01' as [name] ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as [id], N'011' as [name] ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 2 as [id], N'02' as [name] ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "01" }, new tbioudb022 { id = 2, name = "02" }, new tbioudb022 { id = 3, name = "03" }, new tbioudb022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as [id], N'01' as [name] +UNION ALL + SELECT 2, N'02' +UNION ALL + SELECT 3, N'03' +UNION ALL + SELECT 4, N'04' ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "001" }, new tbioudb022 { id = 2, name = "002" }, new tbioudb022 { id = 3, name = "003" }, new tbioudb022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as [id], N'001' as [name] +UNION ALL + SELECT 2, N'002' +UNION ALL + SELECT 3, N'003' +UNION ALL + SELECT 4, N'004' ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);; +SET IDENTITY_INSERT [tbioudb022] OFF;", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "01" }, new tbioudb022 { name = "02" }, new tbioudb022 { name = "03" }, new tbioudb022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'01'), (N'02'), (N'03'), (N'04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { name = "001" }, new tbioudb022 { name = "002" }, new tbioudb022 { name = "003" }, new tbioudb022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbioudb022]([name]) VALUES(N'001'), (N'002'), (N'003'), (N'004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb022 { id = 1, name = "100001" }, new tbioudb022 { name = "00001" }, new tbioudb022 { id = 2, name = "100002" }, new tbioudb022 { name = "00002" }, new tbioudb022 { id = 3, name = "100003" }, new tbioudb022 { name = "00003" }, new tbioudb022 { id = 4, name = "100004" }, new tbioudb022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbioudb022] ON; +MERGE INTO [tbioudb022] t1 +USING (SELECT 1 as [id], N'100001' as [name] +UNION ALL + SELECT 2, N'100002' +UNION ALL + SELECT 3, N'100003' +UNION ALL + SELECT 4, N'100004' ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);; +SET IDENTITY_INSERT [tbioudb022] OFF; + +; + +INSERT INTO [tbioudb022]([name]) VALUES(N'00001'), (N'00002'), (N'00003'), (N'00004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as [id1], N'01' as [id2], N'01' as [name] ) t2 ON (t1.[id1] = t2.[id1] AND t1.[id2] = t2.[id2]) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.[id1], t2.[id2], t2.[name]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as [id1], N'01' as [id2], N'011' as [name] ) t2 ON (t1.[id1] = t2.[id1] AND t1.[id2] = t2.[id2]) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.[id1], t2.[id2], t2.[name]);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 2 as [id1], N'02' as [id2], N'02' as [name] ) t2 ON (t1.[id1] = t2.[id1] AND t1.[id2] = t2.[id2]) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.[id1], t2.[id2], t2.[name]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "01" }, new tbioudb03 { id1 = 2, id2 = "02", name = "02" }, new tbioudb03 { id1 = 3, id2 = "03", name = "03" }, new tbioudb03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as [id1], N'01' as [id2], N'01' as [name] +UNION ALL + SELECT 2, N'02', N'02' +UNION ALL + SELECT 3, N'03', N'03' +UNION ALL + SELECT 4, N'04', N'04' ) t2 ON (t1.[id1] = t2.[id1] AND t1.[id2] = t2.[id2]) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.[id1], t2.[id2], t2.[name]);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb03 { id1 = 1, id2 = "01", name = "001" }, new tbioudb03 { id1 = 2, id2 = "02", name = "002" }, new tbioudb03 { id1 = 3, id2 = "03", name = "003" }, new tbioudb03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb03] t1 +USING (SELECT 1 as [id1], N'01' as [id2], N'001' as [name] +UNION ALL + SELECT 2, N'02', N'002' +UNION ALL + SELECT 3, N'03', N'003' +UNION ALL + SELECT 4, N'04', N'004' ) t2 ON (t1.[id1] = t2.[id1] AND t1.[id2] = t2.[id2]) +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.[id1], t2.[id2], t2.[name]);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id1).Count()); + } + class tbioudb03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as [id], N'01' as [name], 0 as [version], getdate() as [CreateTime] ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.[id], t2.[name], t2.[version], t2.[CreateTime]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as [id], N'011' as [name], 0 as [version], getdate() as [CreateTime] ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.[id], t2.[name], t2.[version], t2.[CreateTime]);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new tbioudb04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 2 as [id], N'02' as [name], 0 as [version], getdate() as [CreateTime] ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.[id], t2.[name], t2.[version], t2.[CreateTime]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "01" }, new tbioudb04 { id = 2, name = "02" }, new tbioudb04 { id = 3, name = "03" }, new tbioudb04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as [id], N'01' as [name], 0 as [version], getdate() as [CreateTime] +UNION ALL + SELECT 2, N'02', 0, getdate() +UNION ALL + SELECT 3, N'03', 0, getdate() +UNION ALL + SELECT 4, N'04', 0, getdate() ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.[id], t2.[name], t2.[version], t2.[CreateTime]);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().IfExistsDoNothing().SetSource(new[] { new tbioudb04 { id = 1, name = "001" }, new tbioudb04 { id = 2, name = "002" }, new tbioudb04 { id = 3, name = "003" }, new tbioudb04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbioudb04] t1 +USING (SELECT 1 as [id], N'001' as [name], 0 as [version], getdate() as [CreateTime] +UNION ALL + SELECT 2, N'002', 0, getdate() +UNION ALL + SELECT 3, N'003', 0, getdate() +UNION ALL + SELECT 4, N'004', 0, getdate() ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.[id], t2.[name], t2.[version], t2.[CreateTime]);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "0" + a.id).Count()); + } + class tbioudb04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs new file mode 100644 index 00000000..cb614e7d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerInsertOrUpdateTest.cs @@ -0,0 +1,464 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServer +{ + public class SqlServerInsertOrUpdateTest + { + IFreeSql fsql => g.sqlserver; + + [Fact] + public void InsertOrUpdate_OnlyPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou01] t1 +USING (SELECT 1 as [id] ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.[id]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 1 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou01] t1 +USING (SELECT 1 as [id] ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.[id]);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou01 { id = 2 }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou01] t1 +USING (SELECT 2 as [id] ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.[id]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou01] t1 +USING (SELECT 1 as [id] +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.[id]);", sql); + Assert.Equal(2, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou01 { id = 1 }, new tbiou01 { id = 2 }, new tbiou01 { id = 3 }, new tbiou01 { id = 4 } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou01] t1 +USING (SELECT 1 as [id] +UNION ALL + SELECT 2 +UNION ALL + SELECT 3 +UNION ALL + SELECT 4 ) t2 ON (t1.[id] = t2.[id]) +WHEN NOT MATCHED THEN + insert ([id]) + values (t2.[id]);", sql); + Assert.Equal(0, iou.ExecuteAffrows()); + } + class tbiou01 + { + public int id { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou02] t1 +USING (SELECT 1 as [id], N'01' as [name] ) t2 ON (t1.[id] = t2.[id]) +WHEN MATCHED THEN + update set [name] = t2.[name] +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou02] t1 +USING (SELECT 1 as [id], N'011' as [name] ) t2 ON (t1.[id] = t2.[id]) +WHEN MATCHED THEN + update set [name] = t2.[name] +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou02 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou02] t1 +USING (SELECT 2 as [id], N'02' as [name] ) t2 ON (t1.[id] = t2.[id]) +WHEN MATCHED THEN + update set [name] = t2.[name] +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "01" }, new tbiou02 { id = 2, name = "02" }, new tbiou02 { id = 3, name = "03" }, new tbiou02 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou02] t1 +USING (SELECT 1 as [id], N'01' as [name] +UNION ALL + SELECT 2, N'02' +UNION ALL + SELECT 3, N'03' +UNION ALL + SELECT 4, N'04' ) t2 ON (t1.[id] = t2.[id]) +WHEN MATCHED THEN + update set [name] = t2.[name] +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou02 { id = 1, name = "001" }, new tbiou02 { id = 2, name = "002" }, new tbiou02 { id = 3, name = "003" }, new tbiou02 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou02] t1 +USING (SELECT 1 as [id], N'001' as [name] +UNION ALL + SELECT 2, N'002' +UNION ALL + SELECT 3, N'003' +UNION ALL + SELECT 4, N'004' ) t2 ON (t1.[id] = t2.[id]) +WHEN MATCHED THEN + update set [name] = t2.[name] +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou02 + { + public int id { get; set; } + public string name { get; set; } + } + [Fact] + public void InsertOrUpdate_OnePrimaryAndIdentity() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 1 as [id], N'01' as [name] ) t2 ON (t1.[id] = t2.[id]) +WHEN MATCHED THEN + update set [name] = t2.[name] +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);; +SET IDENTITY_INSERT [tbiou022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 1 as [id], N'011' as [name] ) t2 ON (t1.[id] = t2.[id]) +WHEN MATCHED THEN + update set [name] = t2.[name] +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);; +SET IDENTITY_INSERT [tbiou022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 2 as [id], N'02' as [name] ) t2 ON (t1.[id] = t2.[id]) +WHEN MATCHED THEN + update set [name] = t2.[name] +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);; +SET IDENTITY_INSERT [tbiou022] OFF;", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "01" }, new tbiou022 { id = 2, name = "02" }, new tbiou022 { id = 3, name = "03" }, new tbiou022 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 1 as [id], N'01' as [name] +UNION ALL + SELECT 2, N'02' +UNION ALL + SELECT 3, N'03' +UNION ALL + SELECT 4, N'04' ) t2 ON (t1.[id] = t2.[id]) +WHEN MATCHED THEN + update set [name] = t2.[name] +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);; +SET IDENTITY_INSERT [tbiou022] OFF;", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "001" }, new tbiou022 { id = 2, name = "002" }, new tbiou022 { id = 3, name = "003" }, new tbiou022 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 1 as [id], N'001' as [name] +UNION ALL + SELECT 2, N'002' +UNION ALL + SELECT 3, N'003' +UNION ALL + SELECT 4, N'004' ) t2 ON (t1.[id] = t2.[id]) +WHEN MATCHED THEN + update set [name] = t2.[name] +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);; +SET IDENTITY_INSERT [tbiou022] OFF;", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + + //--no primary + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "01" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbiou022]([name]) VALUES(N'01')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbiou022]([name]) VALUES(N'011')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou022 { name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbiou022]([name]) VALUES(N'02')", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "01" }, new tbiou022 { name = "02" }, new tbiou022 { name = "03" }, new tbiou022 { name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbiou022]([name]) VALUES(N'01'), (N'02'), (N'03'), (N'04')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { name = "001" }, new tbiou022 { name = "002" }, new tbiou022 { name = "003" }, new tbiou022 { name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"INSERT INTO [tbiou022]([name]) VALUES(N'001'), (N'002'), (N'003'), (N'004')", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + //--no primary and yes + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou022 { id = 1, name = "100001" }, new tbiou022 { name = "00001" }, new tbiou022 { id = 2, name = "100002" }, new tbiou022 { name = "00002" }, new tbiou022 { id = 3, name = "100003" }, new tbiou022 { name = "00003" }, new tbiou022 { id = 4, name = "100004" }, new tbiou022 { name = "00004" } }); + sql = iou.ToSql(); + Assert.Equal(@"SET IDENTITY_INSERT [tbiou022] ON; +MERGE INTO [tbiou022] t1 +USING (SELECT 1 as [id], N'100001' as [name] +UNION ALL + SELECT 2, N'100002' +UNION ALL + SELECT 3, N'100003' +UNION ALL + SELECT 4, N'100004' ) t2 ON (t1.[id] = t2.[id]) +WHEN MATCHED THEN + update set [name] = t2.[name] +WHEN NOT MATCHED THEN + insert ([id], [name]) + values (t2.[id], t2.[name]);; +SET IDENTITY_INSERT [tbiou022] OFF; + +; + +INSERT INTO [tbiou022]([name]) VALUES(N'00001'), (N'00002'), (N'00003'), (N'00004')", sql); + Assert.Equal(8, iou.ExecuteAffrows()); + lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "10000" + a.id).Count()); + } + class tbiou022 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_TwoPrimary() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou03] t1 +USING (SELECT 1 as [id1], N'01' as [id2], N'01' as [name] ) t2 ON (t1.[id1] = t2.[id1] AND t1.[id2] = t2.[id2]) +WHEN MATCHED THEN + update set [name] = t2.[name] +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.[id1], t2.[id2], t2.[name]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 1, id2 = "01", name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou03] t1 +USING (SELECT 1 as [id1], N'01' as [id2], N'011' as [name] ) t2 ON (t1.[id1] = t2.[id1] AND t1.[id2] = t2.[id2]) +WHEN MATCHED THEN + update set [name] = t2.[name] +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.[id1], t2.[id2], t2.[name]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou03 { id1 = 2, id2 = "02", name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou03] t1 +USING (SELECT 2 as [id1], N'02' as [id2], N'02' as [name] ) t2 ON (t1.[id1] = t2.[id1] AND t1.[id2] = t2.[id2]) +WHEN MATCHED THEN + update set [name] = t2.[name] +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.[id1], t2.[id2], t2.[name]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "01" }, new tbiou03 { id1 = 2, id2 = "02", name = "02" }, new tbiou03 { id1 = 3, id2 = "03", name = "03" }, new tbiou03 { id1 = 4, id2 = "04", name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou03] t1 +USING (SELECT 1 as [id1], N'01' as [id2], N'01' as [name] +UNION ALL + SELECT 2, N'02', N'02' +UNION ALL + SELECT 3, N'03', N'03' +UNION ALL + SELECT 4, N'04', N'04' ) t2 ON (t1.[id1] = t2.[id1] AND t1.[id2] = t2.[id2]) +WHEN MATCHED THEN + update set [name] = t2.[name] +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.[id1], t2.[id2], t2.[name]);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou03 { id1 = 1, id2 = "01", name = "001" }, new tbiou03 { id1 = 2, id2 = "02", name = "002" }, new tbiou03 { id1 = 3, id2 = "03", name = "003" }, new tbiou03 { id1 = 4, id2 = "04", name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou03] t1 +USING (SELECT 1 as [id1], N'01' as [id2], N'001' as [name] +UNION ALL + SELECT 2, N'02', N'002' +UNION ALL + SELECT 3, N'03', N'003' +UNION ALL + SELECT 4, N'04', N'004' ) t2 ON (t1.[id1] = t2.[id1] AND t1.[id2] = t2.[id2]) +WHEN MATCHED THEN + update set [name] = t2.[name] +WHEN NOT MATCHED THEN + insert ([id1], [id2], [name]) + values (t2.[id1], t2.[id2], t2.[name]);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => a.id1 == 1 && a.id2 == "01" || a.id1 == 2 && a.id2 == "02" || a.id1 == 3 && a.id2 == "03" || a.id1 == 4 && a.id2 == "04").ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id1).Count()); + } + class tbiou03 + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public string id2 { get; set; } + public string name { get; set; } + } + + [Fact] + public void InsertOrUpdate_OnePrimaryAndVersionAndCanUpdate() + { + fsql.Delete().Where("1=1").ExecuteAffrows(); + var iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "01" }); + var sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou04] t1 +USING (SELECT 1 as [id], N'01' as [name], 0 as [version], getdate() as [CreateTime] ) t2 ON (t1.[id] = t2.[id]) +WHEN MATCHED THEN + update set [name] = t2.[name], [version] = t1.[version] + 1 +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.[id], t2.[name], t2.[version], t2.[CreateTime]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 1, name = "011" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou04] t1 +USING (SELECT 1 as [id], N'011' as [name], 0 as [version], getdate() as [CreateTime] ) t2 ON (t1.[id] = t2.[id]) +WHEN MATCHED THEN + update set [name] = t2.[name], [version] = t1.[version] + 1 +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.[id], t2.[name], t2.[version], t2.[CreateTime]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new tbiou04 { id = 2, name = "02" }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou04] t1 +USING (SELECT 2 as [id], N'02' as [name], 0 as [version], getdate() as [CreateTime] ) t2 ON (t1.[id] = t2.[id]) +WHEN MATCHED THEN + update set [name] = t2.[name], [version] = t1.[version] + 1 +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.[id], t2.[name], t2.[version], t2.[CreateTime]);", sql); + Assert.Equal(1, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "01" }, new tbiou04 { id = 2, name = "02" }, new tbiou04 { id = 3, name = "03" }, new tbiou04 { id = 4, name = "04" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou04] t1 +USING (SELECT 1 as [id], N'01' as [name], 0 as [version], getdate() as [CreateTime] +UNION ALL + SELECT 2, N'02', 0, getdate() +UNION ALL + SELECT 3, N'03', 0, getdate() +UNION ALL + SELECT 4, N'04', 0, getdate() ) t2 ON (t1.[id] = t2.[id]) +WHEN MATCHED THEN + update set [name] = t2.[name], [version] = t1.[version] + 1 +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.[id], t2.[name], t2.[version], t2.[CreateTime]);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + + iou = fsql.InsertOrUpdate().SetSource(new[] { new tbiou04 { id = 1, name = "001" }, new tbiou04 { id = 2, name = "002" }, new tbiou04 { id = 3, name = "003" }, new tbiou04 { id = 4, name = "004" } }); + sql = iou.ToSql(); + Assert.Equal(@"MERGE INTO [tbiou04] t1 +USING (SELECT 1 as [id], N'001' as [name], 0 as [version], getdate() as [CreateTime] +UNION ALL + SELECT 2, N'002', 0, getdate() +UNION ALL + SELECT 3, N'003', 0, getdate() +UNION ALL + SELECT 4, N'004', 0, getdate() ) t2 ON (t1.[id] = t2.[id]) +WHEN MATCHED THEN + update set [name] = t2.[name], [version] = t1.[version] + 1 +WHEN NOT MATCHED THEN + insert ([id], [name], [version], [CreateTime]) + values (t2.[id], t2.[name], t2.[version], t2.[CreateTime]);", sql); + Assert.Equal(4, iou.ExecuteAffrows()); + var lst = fsql.Select().Where(a => new[] { 1, 2, 3, 4 }.Contains(a.id)).ToList(); + Assert.Equal(4, lst.Where(a => a.name == "00" + a.id).Count()); + } + class tbiou04 + { + public int id { get; set; } + public string name { get; set; } + [Column(IsVersion = true)] + public int version { get; set; } + [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)] + public DateTime CreateTime { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerInsertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerInsertTest.cs new file mode 100644 index 00000000..2382bceb --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerInsertTest.cs @@ -0,0 +1,155 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServer +{ + [Collection("SqlServerCollection")] + public class SqlServerInsertTest + { + IInsert insert => g.sqlserver.Insert(); //�������� + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void AppendData() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Parse("2019-09-19 20:09:37.328") }); + + var sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items.First()).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(0, N'newtitle0', '2019-09-19 20:09:37.328')", sql); + + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title], [CreateTime]) VALUES(0, N'newtitle0', '2019-09-19 20:09:37.328'), (100, N'newtitle1', '2019-09-19 20:09:37.328'), (200, N'newtitle2', '2019-09-19 20:09:37.328'), (300, N'newtitle3', '2019-09-19 20:09:37.328'), (400, N'newtitle4', '2019-09-19 20:09:37.328'), (500, N'newtitle5', '2019-09-19 20:09:37.328'), (600, N'newtitle6', '2019-09-19 20:09:37.328'), (700, N'newtitle7', '2019-09-19 20:09:37.328'), (800, N'newtitle8', '2019-09-19 20:09:37.328'), (900, N'newtitle9', '2019-09-19 20:09:37.328')", sql); + + sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(N'newtitle0'), (N'newtitle1'), (N'newtitle2'), (N'newtitle3'), (N'newtitle4'), (N'newtitle5'), (N'newtitle6'), (N'newtitle7'), (N'newtitle8'), (N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + } + + [Fact] + public void InsertColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var sql = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Title]) VALUES(N'newtitle0'), (N'newtitle1'), (N'newtitle2'), (N'newtitle3'), (N'newtitle4'), (N'newtitle5'), (N'newtitle6'), (N'newtitle7'), (N'newtitle8'), (N'newtitle9')", sql); + + sql = insert.AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + } + [Fact] + public void IgnoreColumns() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var sql = insert.AppendData(items).IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + + sql = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime, a.TypeGuid }).ToSql(); + Assert.Equal("INSERT INTO [tb_topic]([Clicks]) VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + + g.sqlserver.Delete().Where("1=1").ExecuteAffrows(); + var itemsIgnore = new List(); + for (var a = 0; a < 2072; a++) itemsIgnore.Add(new TopicIgnore { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + g.sqlserver.Insert().AppendData(itemsIgnore).IgnoreColumns(a => new { a.Title }).ExecuteAffrows(); + Assert.Equal(2072, itemsIgnore.Count); + Assert.Equal(2072, g.sqlserver.Select().Where(a => a.Title == null).Count()); + } + [Table(Name = "tb_topicIgnoreColumns")] + class TopicIgnore + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Equal(1, insert.AppendData(items.First()).ExecuteAffrows()); + Assert.Equal(10, insert.AppendData(items).ExecuteAffrows()); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //Assert.Equal(9989, g.sqlserver.Insert(items).ExecuteAffrows()); + } + [Fact] + public void ExecuteIdentity() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.NotEqual(0, insert.AppendData(items.First()).ExecuteIdentity()); + + + //items = Enumerable.Range(0, 9999).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //var lastId = g.sqlite.Select().Max(a => a.Id); + //Assert.NotEqual(lastId, g.sqlserver.Insert(items).ExecuteIdentity()); + } + [Fact] + public void ExecuteInserted() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + var items2 = insert.AppendData(items).ExecuteInserted(); + + items = Enumerable.Range(0, 90).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + var itemsInserted = g.sqlserver.Insert(items).ExecuteInserted(); + Assert.Equal(items.First().Title, itemsInserted.First().Title); + Assert.Equal(items.Last().Title, itemsInserted.Last().Title); + } + + [Fact] + public void AsTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Parse("2019-09-19 20:01:51.149") }); + + var sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items.First()).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(0, N'newtitle0', '2019-09-19 20:01:51.149')", sql); + + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title], [CreateTime]) VALUES(0, N'newtitle0', '2019-09-19 20:01:51.149'), (100, N'newtitle1', '2019-09-19 20:01:51.149'), (200, N'newtitle2', '2019-09-19 20:01:51.149'), (300, N'newtitle3', '2019-09-19 20:01:51.149'), (400, N'newtitle4', '2019-09-19 20:01:51.149'), (500, N'newtitle5', '2019-09-19 20:01:51.149'), (600, N'newtitle6', '2019-09-19 20:01:51.149'), (700, N'newtitle7', '2019-09-19 20:01:51.149'), (800, N'newtitle8', '2019-09-19 20:01:51.149'), (900, N'newtitle9', '2019-09-19 20:01:51.149')", sql); + + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).InsertColumns(a => a.Title).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(N'newtitle0'), (N'newtitle1'), (N'newtitle2'), (N'newtitle3'), (N'newtitle4'), (N'newtitle5'), (N'newtitle6'), (N'newtitle7'), (N'newtitle8'), (N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.Title, a.TypeGuid }).InsertColumns(a => a.Title).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Title]) VALUES(N'newtitle0'), (N'newtitle1'), (N'newtitle2'), (N'newtitle3'), (N'newtitle4'), (N'newtitle5'), (N'newtitle6'), (N'newtitle7'), (N'newtitle8'), (N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => a.TypeGuid).AppendData(items).InsertColumns(a => new { a.Title, a.Clicks }).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks], [Title]) VALUES(0, N'newtitle0'), (100, N'newtitle1'), (200, N'newtitle2'), (300, N'newtitle3'), (400, N'newtitle4'), (500, N'newtitle5'), (600, N'newtitle6'), (700, N'newtitle7'), (800, N'newtitle8'), (900, N'newtitle9')", sql); + + sql = insert.IgnoreColumns(a => new { a.CreateTime, a.Title, a.TypeGuid }).AppendData(items).AsTable(a => "tb_topicAsTable").ToSql(); + Assert.Equal("INSERT INTO [tb_topicAsTable]([Clicks]) VALUES(0), (100), (200), (300), (400), (500), (600), (700), (800), (900)", sql); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerSelectTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerSelectTest.cs new file mode 100644 index 00000000..89258fa7 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerSelectTest.cs @@ -0,0 +1,1819 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServer +{ + public class SqlServerSelectTest + { + ISelect select => g.sqlserver.Select(); + + [Table(Name = "tb_topic22")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + public partial class Song + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public DateTime? Create_time { get; set; } + public bool? Is_deleted { get; set; } + public string Title { get; set; } + public string Url { get; set; } + + public virtual ICollection Tags { get; set; } + } + public partial class Song_tag + { + public int Song_id { get; set; } + public virtual Song Song { get; set; } + + public int Tag_id { get; set; } + public virtual Tag Tag { get; set; } + } + public partial class Tag + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public int? Parent_id { get; set; } + public virtual Tag Parent { get; set; } + + public decimal? Ddd { get; set; } + public string Name { get; set; } + + public virtual ICollection Songs { get; set; } + public virtual ICollection Tags { get; set; } + } + + [Fact] + public void AsSelect() + { + //OneToOne、ManyToOne + var t0 = g.sqlserver.Select().Where(a => a.Parent.Parent.Name == "粤语").ToSql(); + //SELECT a.[Id], a.[Parent_id], a__Parent.[Id] as3, a__Parent.[Parent_id] as4, a__Parent.[Ddd], a__Parent.[Name], a.[Ddd] as7, a.[Name] as8 + //FROM [Tag] a + //LEFT JOIN [Tag] a__Parent ON a__Parent.[Id] = a.[Parent_id] + //LEFT JOIN [Tag] a__Parent__Parent ON a__Parent__Parent.[Id] = a__Parent.[Parent_id] + //WHERE (a__Parent__Parent.[Name] = '粤语') + + //OneToMany + var t1 = g.sqlserver.Select().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToSql(); + //SELECT a.[Id], a.[Parent_id], a.[Ddd], a.[Name] + //FROM [Tag] a + //WHERE (exists(SELECT 1 + // FROM [Tag] t + // LEFT JOIN [Tag] t__Parent ON t__Parent.[Id] = t.[Parent_id] + // WHERE (t__Parent.[Id] = 10) AND (t.[Parent_id] = a.[Id]) + // limit 0,1)) + + //ManyToMany + var t2 = g.sqlserver.Select().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToSql(); + //SELECT a.[Id], a.[Create_time], a.[Is_deleted], a.[Title], a.[Url] + //FROM [Song] a + //WHERE(exists(SELECT 1 + // FROM [Song_tag] Mt_Ms + // WHERE(Mt_Ms.[Song_id] = a.[Id]) AND(exists(SELECT 1 + // FROM [Tag] t + // WHERE(t.[Name] = '国语') AND(t.[Id] = Mt_Ms.[Tag_id]) + // limit 0, 1)) + // limit 0, 1)) + } + + [Fact] + public void Lazy() + { + var tags = g.sqlserver.Select().Where(a => a.Parent.Name == "xxx") + .LeftJoin(a => a.Parent_id == a.Parent.Id) + .ToSql(); + + var songs = g.sqlserver.Select().Limit(10).ToList(); + + + } + [Fact] + public void ToDataTable() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100, CreateTime = DateTime.Now }); + + Assert.Single(g.sqlserver.Insert().AppendData(items.First()).ExecuteInserted()); + Assert.Equal(10, g.sqlserver.Insert().AppendData(items).ExecuteInserted().Count); + + //items = Enumerable.Range(0, 9989).Select(a => new Topic { Title = "newtitle" + a, CreateTime = DateTime.Now }).ToList(); + //; + //Assert.Equal(9989, g.sqlserver.Insert(items).NoneParameter().ExecuteAffrows()); + + var dt1 = select.Limit(10).ToDataTable(); + var dt2 = select.Limit(10).ToDataTable("Id, getdate()"); + var dt3 = select.Limit(10).ToDataTable(a => new { a.Id, a.Type.Name, now = DateTime.Now }); + } + class TestDto + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + } + class TestDto2 + { + public int id { get; set; } + public string name { get; set; } //这是join表的属性 + public int ParentId { get; set; } //这是join表的属性 + + public TestDto2() { } + public TestDto2(int id, string name) + { + this.id = id; + this.name = name; + } + } + [Fact] + public void ToList() + { + var testDto1 = select.Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto2 = select.Limit(10).ToList(a => new TestDto()); + var testDto3 = select.Limit(10).ToList(a => new TestDto { }); + var testDto4 = select.Limit(10).ToList(a => new TestDto() { }); + + var testDto11 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { id = a.Id, name = a.Title }); + var testDto22 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto()); + var testDto33 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto { }); + var testDto44 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto() { }); + + var testDto211 = select.Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto212 = select.Limit(10).ToList(a => new TestDto2()); + var testDto213 = select.Limit(10).ToList(a => new TestDto2 { }); + var testDto214 = select.Limit(10).ToList(a => new TestDto2() { }); + var testDto215 = select.Limit(10).ToList(); + + var testDto2211 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2(a.Id, a.Title)); + var testDto2222 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2()); + var testDto2233 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2 { }); + var testDto2244 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(a => new TestDto2() { }); + var testDto2255 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).Limit(10).ToList(); + + g.sqlserver.Insert().AppendData(new TestGuidIdToList()).ExecuteAffrows(); + var testGuidId5 = g.sqlserver.Select().ToList(); + var testGuidId6 = g.sqlserver.Select().ToList(a => a.id); + + var t11 = select.Where(a => a.Type.Name.Length > 0).ToList(true); + var t21 = select.Where(a => a.Type.Parent.Name.Length > 0).ToList(true); + + g.sqlserver.Delete().Where("1=1").ExecuteAffrows(); + var repo = g.sqlserver.GetRepository(); + repo.DbContextOptions.EnableCascadeSave = true; + repo.Insert(new District + { + Code = "001", + Name = "001_name", + Childs = new List(new[] { + new District{ + Code = "001_01", + Name = "001_01_name" + }, + new District{ + Code = "001_02", + Name = "001_02_name" + } + }) + }); + var ddd = g.sqlserver.Select().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList(); + Assert.Single(ddd); + Assert.Equal(2, ddd[0].Childs.Count); + } + public class District + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public string ParentCode { get; set; } + + [Navigate(nameof(ParentCode))] + public District Parent { get; set; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Fact] + public void ToDictionary() + { + var testDto1 = select.Limit(10).ToDictionary(a => a.Id); + var testDto2 = select.Limit(10).ToDictionary(a => a.Id, a => new { a.Id, a.Title }); + + var repo = g.sqlserver.GetRepository(); + var dic = repo.Select.Limit(10).ToDictionary(a => a.Id); + var first = dic.First().Value; + first.Clicks++; + repo.Update(first); + } + class TestGuidIdToList + { + public Guid id { get; set; } + public string title { get; set; } = Guid.NewGuid().ToString(); + } + [Fact] + public void ToOne() + { + var testnotfind = select.Where("1=2").First(a => a.CreateTime); + Assert.Equal(default(DateTime), testnotfind); + } + [Fact] + public void ToSql() + { + } + [Fact] + public void Any() + { + var count = select.Where(a => 1 == 1).Count(); + Assert.False(select.Where(a => 1 == 2).Any()); + Assert.Equal(count > 0, select.Where(a => 1 == 1).Any()); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any(c => c.Id == a.Id + 10) + ); + var sql2222Tolist = sql2222.ToList(); + + var collectionSelect = select.Where(a => + a.Type.Guid == a.TypeGuid && + a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any(b => b.ParentId == a.Type.Parent.Id) + ); + collectionSelect.ToList(); + } + [Fact] + public void Count() + { + var count = select.Where(a => 1 == 1).Count(); + select.Where(a => 1 == 1).Count(out var count2); + Assert.Equal(count, count2); + Assert.Equal(0, select.Where(a => 1 == 2).Count()); + + var subquery = select.ToSql(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.Where(b => b.Id > 0 && b.Id == a.Id).Count() + }); + } + [Fact] + public void Master() + { + Assert.StartsWith(" SELECT", select.Master().Where(a => 1 == 1).ToSql()); + } + + [Fact] + public void From() + { + var query2 = select.From((s, b) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + ); + var sql2 = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid]", sql2); + query2.ToList(); + + var query3 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id) + ); + var sql3 = query3.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql3); + query3.ToList(); + } + [Fact] + public void LeftJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + query = select + .LeftJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] c ON c.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + } + [Fact] + public void InnerJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.InnerJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.InnerJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //������� + query = select + .InnerJoin(a => a.Type.Guid == a.TypeGuid) + .InnerJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] INNER JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + query = select + .InnerJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .InnerJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] INNER JOIN [TestTypeParentInfo] c ON c.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .InnerJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] INNER JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.InnerJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a INNER JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + } + [Fact] + public void RightJoin() + { + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.RightJoin(a => a.Type.Guid == a.TypeGuid); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.RightJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx' LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //���û�е������� + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid]", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx'", sql); + query.ToList(); + + query = select.RightJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx' LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + query.ToList(); + + //������� + query = select + .RightJoin(a => a.Type.Guid == a.TypeGuid) + .RightJoin(a => a.Type.Parent.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] RIGHT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + query = select + .RightJoin((a, a__Type) => a__Type.Guid == a.TypeGuid) + .RightJoin((a, c) => c.Id == a.Type.ParentId); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] RIGHT JOIN [TestTypeParentInfo] c ON c.[Id] = a__Type.[ParentId]", sql); + query.ToList(); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .RightJoin(a => a.TypeGuid == b.Guid) + .RightJoin(a => b.ParentId == c.Id)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN [TestTypeInfo] b ON a.[TypeGuid] = b.[Guid] RIGHT JOIN [TestTypeParentInfo] c ON b.[ParentId] = c.[Id]", sql); + query2.ToList(); + + //������϶����㲻�� + query = select.RightJoin("TestTypeInfo b on b.Guid = a.TypeGuid"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a RIGHT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + query.ToList(); + } + [Fact] + public void Where() + { + var sqltmp1 = select.Where(a => a.Id == 0 && (a.Title == "x" || a.Title == "y") && a.Clicks == 1).ToSql(); + var sqltmp2 = select.Where(a => a.Id.Equals(true) && (a.Title.Equals("x") || a.Title.Equals("y")) && a.Clicks.Equals(1)).ToSql(); + var sqltmp3 = select.Where(a => a.Id == 0).Where(a => ((a.Title == "x" && a.Title == "z") || a.Title == "y")).ToSql(); + + var sqltmp4 = select.Where(a => (a.Id - 10) / 2 > 0).ToSql(); + + //����е�������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], a.[Clicks], a.[TypeGuid], 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], a.[Clicks], a.[TypeGuid], 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], a.[Clicks], a.[TypeGuid], 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], a.[Clicks], a.[TypeGuid], 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.[TypeGuid] WHERE (a__Type.[Name] = N'typeTitle')", sql); + query.ToList(); + + query = select.Where(a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = N'typeTitle' AND a__Type.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.Where(a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Name] = N'tparent')", sql); + query.ToList(); + + //���û�е������ԣ��򵥶������ + query = select.Where((a, b) => b.Guid == a.TypeGuid && b.Name == "typeTitle"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Guid] = a.[TypeGuid] AND b.[Name] = N'typeTitle')", sql); + query.ToList(); + + query = select.Where((a, b) => b.Name == "typeTitle" && b.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b WHERE (b.[Name] = N'typeTitle' AND b.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.Where((a, b, c) => c.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeParentInfo] c WHERE (c.[Name] = N'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .Where(a => a.Id == 10 && c.Name == "xxx") + .Where(a => b.ParentId == 20)); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = N'xxx') AND (b.[ParentId] = 20)", sql); + query2.ToList(); + } + [Fact] + public void WhereIf() + { + //����е�������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], a.[Clicks], a.[TypeGuid], 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], a.[Clicks], a.[TypeGuid], 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], a.[Clicks], a.[TypeGuid], 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], a.[Clicks], a.[TypeGuid], 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.[TypeGuid] WHERE (a__Type.[Name] = N'typeTitle')", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] WHERE (a__Type.[Name] = N'typeTitle' AND a__Type.[Guid] = a.[TypeGuid])", sql); + query.ToList(); + + query = select.WhereIf(true, a => a.Type.Parent.Name == "tparent"); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22] a LEFT JOIN [TestTypeInfo] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfo] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Name] = N'tparent')", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + var query2 = select.From((s, b, c) => s + .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], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c WHERE (a.[Id] = 10 AND c.[Name] = N'xxx') AND (b.[ParentId] = 20)", sql); + query2.ToList(); + + // ==========================================WhereIf(false) + + //����е�������a.Type��a.Type.Parent ���ǵ������� + query = select.WhereIf(false, a => a.Id == 10); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], 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], a.[Clicks], a.[TypeGuid], 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], a.[Clicks], a.[TypeGuid], 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], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + query = select.WhereIf(false, a => a.Type.Name == "typeTitle" && a.Type.Guid == a.TypeGuid); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], 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], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a", sql); + query.ToList(); + + //����һ�� From ��Ķ������ + query2 = select.From((s, b, c) => s + .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], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a, [TestTypeInfo] b, [TestTypeParentInfo] c", sql); + query2.ToList(); + } + [Fact] + public void WhereExists() + { + var sql2222 = select.Where(a => select.Where(b => b.Id == a.Id).Any()).ToList(); + + sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + + //.Offset(a.Id) + + .Any() + ).Any() + ).ToList(); + } + [Fact] + public void GroupBy() + { + var groupby = select.From((s, b, c) => s + .Where(a => a.Id == 1) + ) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .Offset(10) + .Limit(2) + .Count(out var trycount) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + cou2 = a.Count(a.Value.Item3.Id), + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + ccc3 = a.Max(a.Value.Item3.Id) + }); + + var testpid1 = g.sqlserver.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.sqlserver.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var fkfjfj = select.GroupBy(a => a.Title) + .ToList(a => a.Sum(a.Value.TypeGuid)); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist11 = select + .GroupBy(a => a.Title) + .ToDictionary(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist22 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToDictionary(b => new + { + b.Key.Title, + b.Key.yyyy, + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Id) + }); + } + [Fact] + public void ToAggregate() + { + var sql = select.ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(Convert.ToInt64(a.Key.Id)), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + } + [Fact] + public void OrderBy() + { + var sql = select.OrderBy(a => new Random().NextDouble()).ToList(); + } + [Fact] + public void OrderByRandom() + { + var t1 = select.OrderByRandom().Limit(10).ToSql("1"); + Assert.Equal(@"SELECT TOP 10 1 +FROM [tb_topic22] a +ORDER BY newid()", t1); + var t2 = select.OrderByRandom().Limit(10).ToList(); + } + + [Fact] + public void Skip_Offset() + { + var sql = select.Offset(10).Limit(10).ToList(); + } + [Fact] + public void Take_Limit() + { + var sql = select.Limit(10).ToList(); + } + [Fact] + public void Page() + { + var sql1 = select.Page(1, 10).ToList(); + var sql2 = select.Page(2, 10).ToList(); + var sql3 = select.Page(3, 10).ToList(); + + var sql11 = select.OrderBy(a => new Random().NextDouble()).Page(1, 10).ToList(); + var sql22 = select.OrderBy(a => new Random().NextDouble()).Page(2, 10).ToList(); + var sql33 = select.OrderBy(a => new Random().NextDouble()).Page(3, 10).ToList(); + } + [Fact] + public void Distinct() + { + var t1 = select.Distinct().ToList(a => a.Title); + var t2 = select.Distinct().Limit(10).ToList(a => a.Title); + } + + [Fact] + public void Sum() + { + var subquery = select.ToSql(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, isnull((SELECT sum(b.[Id]) + FROM [tb_topic22] b), 0) as6 +FROM [tb_topic22] a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = (long)select.As("b").Sum(b => b.Id) + }); + } + [Fact] + public void Min() + { + var subquery = select.ToSql(a => new + { + all = a, + min = select.As("b").Min(b => b.Id), + min2 = select.As("b").Min(b => b.CreateTime) + }); + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, isnull((SELECT min(b.[Id]) + FROM [tb_topic22] b), 0) as6, isnull((SELECT min(b.[CreateTime]) + FROM [tb_topic22] b), '1970-01-01 00:00:00.000') as7 +FROM [tb_topic22] a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + min = select.As("b").Min(b => b.Id), + min2 = select.As("b").Min(b => b.CreateTime), + min3 = select.As("b").Where(b => b.Id < 0).Min(b => b.CreateTime) + }); + } + [Fact] + public void Max() + { + var subquery = select.ToSql(a => new + { + all = a, + max = select.As("b").Max(b => b.Id), + max2 = select.As("b").Max(b => b.CreateTime) + }); + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, isnull((SELECT max(b.[Id]) + FROM [tb_topic22] b), 0) as6, isnull((SELECT max(b.[CreateTime]) + FROM [tb_topic22] b), '1970-01-01 00:00:00.000') as7 +FROM [tb_topic22] a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + max = select.As("b").Max(b => b.Id), + max2 = select.As("b").Max(b => b.CreateTime) + }); + } + [Fact] + public void Avg() + { + var subquery = select.ToSql(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, isnull((SELECT avg(b.[Id]) + FROM [tb_topic22] b), 0) as6 +FROM [tb_topic22] a", subquery); + var subqueryList = select.ToList(a => new + { + all = a, + count = select.As("b").Avg(b => b.Id) + }); + } + [Fact] + public void WhereIn() + { + var subquery = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToSql(); + Assert.Equal(@"SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] +FROM [tb_topic22] a +WHERE (((cast(a.[Id] as nvarchar(100))) in (SELECT b.[Title] + FROM [tb_topic22] b)))", subquery); + var subqueryList = select.Where(a => select.As("b").ToList(b => b.Title).Contains(a.Id.ToString())).ToList(); + } + [Fact] + public void As() + { + } + + [Fact] + public void AsTable() + { + + var listt = select.AsTable((a, b) => "(select * from tb_topic22 where Clicks > 10)").Page(1, 10).ToList(); + + Func tableRule = (type, oldname) => + { + if (type == typeof(Topic)) return oldname + "AsTable1"; + else if (type == typeof(TestTypeInfo)) return oldname + "AsTable2"; + return oldname + "AsTable"; + }; + + //����е�������a.Type��a.Type.Parent ���ǵ������� + var query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).AsTable(tableRule); + var sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid]", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx'", sql); + + query = select.LeftJoin(a => a.Type.Guid == a.TypeGuid && a.Type.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] AND a__Type.[Name] = N'xxx' LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + + //���û�е������� + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid]", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx'", sql); + + query = select.LeftJoin((a, b) => b.Guid == a.TypeGuid && b.Name == "xxx").Where(a => a.Type.Parent.Id == 10).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] AND b.[Name] = N'xxx' LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId] WHERE (a__Type__Parent.[Id] = 10)", sql); + + //������� + query = select + .LeftJoin(a => a.Type.Guid == a.TypeGuid) + .LeftJoin(a => a.Type.Parent.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a__Type.[Guid], a__Type.[ParentId], a__Type.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfoAsTable] a__Type__Parent ON a__Type__Parent.[Id] = a__Type.[ParentId]", sql); + + query = select + .LeftJoin((a, b) => b.Guid == a.TypeGuid) + .LeftJoin((a, c) => c.Id == a.Type.ParentId).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] a__Type ON a__Type.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeInfoAsTable2] b ON b.[Guid] = a.[TypeGuid] LEFT JOIN [TestTypeParentInfoAsTable] c ON c.[Id] = a__Type.[ParentId]", sql); + + //���û�е�������b��c������ϵ + var query2 = select.From((s, b, c) => s + .LeftJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => b.ParentId == c.Id)).AsTable(tableRule); + sql = query2.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], b.[Guid], b.[ParentId], b.[Name], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN [TestTypeInfoAsTable2] b ON a.[TypeGuid] = b.[Guid] LEFT JOIN [TestTypeParentInfoAsTable] c ON b.[ParentId] = c.[Id]", sql); + + //������϶����㲻�� + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid", sql); + + query = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", new { bname = "xxx" }).AsTable(tableRule); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22AsTable1] a LEFT JOIN TestTypeInfo b on b.Guid = a.TypeGuid and b.Name = @bname", sql); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb UNION ALL SELECT * from (SELECT a.[Id], a.[Clicks], a.[TypeGuid], a.[Title], a.[CreateTime] FROM [tb_topic22] a) ftb", sql); + query.ToList(); + + query = select.AsTable((_, old) => old).AsTable((_, old) => old); + sql = query.ToSql("count(1) as1").Replace("\r\n", ""); + Assert.Equal("SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb UNION ALL SELECT * from (SELECT count(1) as1 FROM [tb_topic22] a) ftb", sql); + query.Count(); + + select.AsTable((_, old) => old).AsTable((_, old) => old).Max(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Min(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Sum(a => a.Id); + select.AsTable((_, old) => old).AsTable((_, old) => old).Avg(a => a.Id); + + var sqlsss = select + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_1" : null) + .AsTable((type, old) => type == typeof(Topic) ? $"{old}_2" : null) + .ToSql(a => new + { + a.Id, + a.Clicks + }, FieldAliasOptions.AsProperty); + + var slsld3 = select + .AsTable((type, old) => type == typeof(Topic) ? $"({sqlsss})" : null) + .Page(1, 20) + .ToList(a => new + { + a.Id, + a.Clicks + }); + } + + public class TestInclude_OneToManyModel1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public virtual TestInclude_OneToManyModel2 model2 { get; set; } + + public string m1name { get; set; } + } + public class TestInclude_OneToManyModel2 + { + [Column(IsPrimary = true)] + public int model2id { get; set; } + public virtual TestInclude_OneToManyModel1 model1 { get; set; } + + public string m2setting { get; set; } + + public List childs { get; set; } + } + public class TestInclude_OneToManyModel3 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model2111Idaaa { get; set; } + public string title { get; set; } + + public List childs2 { get; set; } + } + public class TestInclude_OneToManyModel4 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public int model3333Id333 { get; set; } + public string title444 { get; set; } + } + + [Fact] + public void Include_OneToMany() + { + var model1 = new TestInclude_OneToManyModel1 { m1name = DateTime.Now.Second.ToString() }; + model1.id = (int)g.sqlserver.Insert(model1).ExecuteIdentity(); + var model2 = new TestInclude_OneToManyModel2 { model2id = model1.id, m2setting = DateTime.Now.Second.ToString() }; + g.sqlserver.Insert(model2).ExecuteAffrows(); + + var model3_1 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__111" }; + model3_1.id = (int)g.sqlserver.Insert(model3_1).ExecuteIdentity(); + var model3_2 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__222" }; + model3_2.id = (int)g.sqlserver.Insert(model3_2).ExecuteIdentity(); + var model3_3 = new TestInclude_OneToManyModel3 { model2111Idaaa = model1.id, title = "testmodel3__333" }; + model3_3.id = (int)g.sqlserver.Insert(model3_2).ExecuteIdentity(); + + var model4s = new[] { + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_1.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__111" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__222" }, + new TestInclude_OneToManyModel4{ model3333Id333 = model3_2.id, title444 = "testmodel3_4__333" } + }; + Assert.Equal(5, g.sqlserver.Insert(model4s).ExecuteAffrows()); + + var t0 = g.sqlserver.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t1 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t2 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + var t00 = g.sqlserver.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id)) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var t11 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id)) + .Where(a => a.id <= model1.id) + .ToList(); + + var t22 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id))) + .Where(a => a.id <= model1.id) + .ToList(); + + //---- Select ---- + + var at0 = g.sqlserver.Select() + .IncludeMany(a => a.childs.Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at1 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at2 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + + var at00 = g.sqlserver.Select() + .IncludeMany(a => a.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.model2id <= model1.id) + .ToList(); + + var at11 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id })) + .Where(a => a.id <= model1.id) + .ToList(); + + var at22 = g.sqlserver.Select() + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2111Idaaa == a.model2.model2id).Select(m3 => new TestInclude_OneToManyModel3 { id = m3.id }), + then => then.IncludeMany(m3 => m3.childs2.Take(2).Where(m4 => m4.model3333Id333 == m3.id).Select(m4 => new TestInclude_OneToManyModel4 { id = m4.id }))) + .Where(a => a.id <= model1.id) + .ToList(); + } + + public class TestInclude_OneToManyModel11 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2id { get; set; } + public string m3setting { get; set; } + public TestInclude_OneToManyModel22 model2 { get; set; } + public string m1name { get; set; } + } + + public class TestInclude_OneToManyModel22 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string m2setting { get; set; } + public string aaa { get; set; } + public string bbb { get; set; } + public List childs { get; set; } + } + public class TestInclude_OneToManyModel33 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public int model2Id { get; set; } + public string title { get; set; } + public string setting { get; set; } + } + [Fact] + public void Include_OneToMany2() + { + string setting = "x"; + var model2 = new TestInclude_OneToManyModel22 { m2setting = DateTime.Now.Second.ToString(), aaa = "aaa" + DateTime.Now.Second, bbb = "bbb" + DateTime.Now.Second }; + model2.id = (int)g.sqlserver.Insert(model2).ExecuteIdentity(); + + var model3s = new[] + { + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__111", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__222", setting = setting}, + new TestInclude_OneToManyModel33 {model2Id = model2.id, title = "testmodel3__333", setting = setting} + }; + Assert.Equal(3, g.sqlserver.Insert(model3s).ExecuteAffrows()); + + var model1 = new TestInclude_OneToManyModel11 { m1name = DateTime.Now.Second.ToString(), model2id = model2.id, m3setting = setting }; + model1.id = (int)g.sqlserver.Insert(model1).ExecuteIdentity(); + + var t1 = g.sqlserver.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + var t11 = g.sqlserver.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting)) + .Where(a => a.id <= model1.id) + .ToList(true); + + //---- Select ---- + + var at1 = g.sqlserver.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + + var at11 = g.sqlserver.Select() + .LeftJoin(a => a.model2id == a.model2.id) + .IncludeMany(a => a.model2.childs.Take(1).Where(m3 => m3.model2Id == a.model2.id && m3.setting == a.m3setting).Select(m3 => new TestInclude_OneToManyModel33 { title = m3.title })) + .Where(a => a.id <= model1.id) + .ToList(true); + } + + [Fact] + public void Include_OneToChilds() + { + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_中国" + }; + tag1.Id = (int)g.sqlserver.Insert(tag1).ExecuteIdentity(); + var tag1_1 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_北京" + }; + tag1_1.Id = (int)g.sqlserver.Insert(tag1_1).ExecuteIdentity(); + var tag1_2 = new Tag + { + Parent_id = tag1.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_01_上海" + }; + tag1_2.Id = (int)g.sqlserver.Insert(tag1_2).ExecuteIdentity(); + + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_美国" + }; + tag2.Id = (int)g.sqlserver.Insert(tag2).ExecuteIdentity(); + var tag2_1 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_纽约" + }; + tag2_1.Id = (int)g.sqlserver.Insert(tag2_1).ExecuteIdentity(); + var tag2_2 = new Tag + { + Parent_id = tag2.Id, + Ddd = DateTime.Now.Second, + Name = "test_oneToChilds_02_华盛顿" + }; + tag2_2.Id = (int)g.sqlserver.Insert(tag2_2).ExecuteIdentity(); + + var tags0 = g.sqlserver.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags1 = g.sqlserver.Select() + .IncludeMany(a => a.Tags) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags2 = g.sqlserver.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags3 = g.sqlserver.Select() + .IncludeMany(a => a.Tags, + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs).IncludeMany(a => a.Tags)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags11 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags22 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var tags33 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1)).IncludeMany(a => a.Tags.Take(1))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1)) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + // --- Select --- + + var atags0 = g.sqlserver.Select() + .Include(a => a.Parent) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags1 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags2 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs)) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags3 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags11 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags22 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + + var atags33 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.Include(a => a.Parent).IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })).IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }))) + .Include(a => a.Parent) + .IncludeMany(a => a.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Id == tag1.Id || a.Id == tag2.Id) + .ToList(); + } + + [Fact] + public void Include_ManyToMany() + { + + var tag1 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_01_中国" + }; + tag1.Id = (int)g.sqlserver.Insert(tag1).ExecuteIdentity(); + var tag2 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_02_美国" + }; + tag2.Id = (int)g.sqlserver.Insert(tag2).ExecuteIdentity(); + var tag3 = new Tag + { + Ddd = DateTime.Now.Second, + Name = "test_manytoMany_03_日本" + }; + tag3.Id = (int)g.sqlserver.Insert(tag3).ExecuteIdentity(); + + var song1 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_01_我是中国人.mp3", + Url = "http://ww.baidu.com/" + }; + song1.Id = (int)g.sqlserver.Insert(song1).ExecuteIdentity(); + var song2 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_02_爱你一万年.mp3", + Url = "http://ww.163.com/" + }; + song2.Id = (int)g.sqlserver.Insert(song2).ExecuteIdentity(); + var song3 = new Song + { + Create_time = DateTime.Now, + Title = "test_manytoMany_03_千年等一回.mp3", + Url = "http://ww.sina.com/" + }; + song3.Id = (int)g.sqlserver.Insert(song3).ExecuteIdentity(); + + g.sqlserver.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.sqlserver.Insert(new Song_tag { Song_id = song2.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.sqlserver.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag1.Id }).ExecuteAffrows(); + g.sqlserver.Insert(new Song_tag { Song_id = song1.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.sqlserver.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag2.Id }).ExecuteAffrows(); + g.sqlserver.Insert(new Song_tag { Song_id = song3.Id, Tag_id = tag3.Id }).ExecuteAffrows(); + + var songs1 = g.sqlserver.Select() + .IncludeMany(a => a.Tags) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var songs2 = g.sqlserver.Select() + .IncludeMany(a => a.Tags, + then => then.IncludeMany(t => t.Songs)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var tags3 = g.sqlserver.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var songs11 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1)) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var songs22 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1), + then => then.IncludeMany(t => t.Songs.Take(1))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var tags33 = g.sqlserver.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1)) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + // --- Select --- + + new List(new[] { song1, song2, song3 }).IncludeMany(g.sqlserver, a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })); + + var asongs1 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs1.Count); + Assert.Equal(2, songs1[0].Tags.Count); + Assert.Equal(1, songs1[1].Tags.Count); + Assert.Equal(3, songs1[2].Tags.Count); + + var asongs2 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs2.Count); + Assert.Equal(2, songs2[0].Tags.Count); + Assert.Equal(1, songs2[1].Tags.Count); + Assert.Equal(3, songs2[2].Tags.Count); + + var atags3 = g.sqlserver.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + + + var asongs11 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name })) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs11.Count); + Assert.Equal(1, songs11[0].Tags.Count); + Assert.Equal(1, songs11[1].Tags.Count); + Assert.Equal(1, songs11[2].Tags.Count); + + var asongs22 = g.sqlserver.Select() + .IncludeMany(a => a.Tags.Take(1).Select(b => new Tag { Id = b.Id, Name = b.Name }), + then => then.IncludeMany(t => t.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title }))) + .Where(a => a.Id == song1.Id || a.Id == song2.Id || a.Id == song3.Id) + .ToList(); + Assert.Equal(3, songs22.Count); + Assert.Equal(1, songs22[0].Tags.Count); + Assert.Equal(1, songs22[1].Tags.Count); + Assert.Equal(1, songs22[2].Tags.Count); + + var atags33 = g.sqlserver.Select() + .Include(a => a.Tag.Parent) + .IncludeMany(a => a.Tag.Songs.Take(1).Select(b => new Song { Id = b.Id, Title = b.Title })) + .Where(a => a.Tag.Id == tag1.Id || a.Tag.Id == tag2.Id) + .ToList(true); + } + + public class ToDel1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToDel2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToDel3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToDelete() + { + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToDel1Pk{ name = "name1"}, + new ToDel1Pk{ name = "name2"}, + new ToDel1Pk{ name = "nick1"}, + new ToDel1Pk{ name = "nick2"}, + new ToDel1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.sqlserver.Select().Count()); + Assert.Equal(3, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToDel2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.sqlserver.Select().Count()); + Assert.Equal(3, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToDel3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToDelete().ExecuteAffrows()); + Assert.Equal(3, g.sqlserver.Select().Count()); + Assert.Equal(3, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + public class ToUpd1Pk + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + public class ToUpd2Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public string pk2 { get; set; } + public string name { get; set; } + } + public class ToUpd3Pk + { + [Column(IsPrimary = true)] + public Guid pk1 { get; set; } + [Column(IsPrimary = true)] + public int pk2 { get; set; } + [Column(IsPrimary = true)] + public string pk3 { get; set; } + public string name { get; set; } + } + [Fact] + public void ToUpdate() + { + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToUpd1Pk{ name = "name1"}, + new ToUpd1Pk{ name = "name2"}, + new ToUpd1Pk{ name = "nick1"}, + new ToUpd1Pk{ name = "nick2"}, + new ToUpd1Pk{ name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.sqlserver.Select().Count()); + Assert.Equal(5, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "name2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick1"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick2"}, + new ToUpd2Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = "pk2", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.sqlserver.Select().Count()); + Assert.Equal(5, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + + g.sqlserver.Select().ToDelete().ExecuteAffrows(); + Assert.Equal(0, g.sqlserver.Select().Count()); + g.sqlserver.Insert(new[] { + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "name2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick1"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick2"}, + new ToUpd3Pk{ pk1 = FreeUtil.NewMongodbId(), pk2 = 1, pk3 = "pk3", name = "nick3"} + }).ExecuteAffrows(); + Assert.Equal(2, g.sqlserver.Select().Where(a => a.name.StartsWith("name")).ToUpdate().Set(a => a.name, "nick?").ExecuteAffrows()); + Assert.Equal(5, g.sqlserver.Select().Count()); + Assert.Equal(5, g.sqlserver.Select().Where(a => a.name.StartsWith("nick")).Count()); + } + + [Fact] + public void ForUpdate() + { + var orm = g.sqlserver; + + Assert.Equal("安全起见,请务必在事务开启之后,再使用 ForUpdate", + Assert.Throws(() => orm.Select().ForUpdate().Limit(1).ToList())?.Message); + + orm.Transaction(() => + { + var sql = orm.Select().ForUpdate().Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a With(UpdLock, RowLock)", sql); + orm.Select().ForUpdate().Limit(1).ToList(); + + sql = orm.Select().ForUpdate(true).Limit(1).ToSql().Replace("\r\n", ""); + Assert.Equal("SELECT TOP 1 a.[id], a.[name] FROM [ToUpd1Pk] a With(UpdLock, RowLock, NoWait)", sql); + orm.Select().ForUpdate(true).Limit(1).ToList(); + }); + } + + [Fact] + public void ToTreeList() + { + var fsql = g.sqlserver; + fsql.Delete().Where("1=1").ExecuteAffrows(); + var repo = fsql.GetRepository(); + repo.DbContextOptions.EnableCascadeSave = true; + repo.DbContextOptions.NoneParameter = true; + repo.Insert(new VM_District_Child + { + Code = "100000", + Name = "中国", + Childs = new List(new[] { + new VM_District_Child + { + Code = "110000", + Name = "北京", + Childs = new List(new[] { + new VM_District_Child{ Code="110100", Name = "北京市" }, + new VM_District_Child{ Code="110101", Name = "东城区" }, + }) + } + }) + }); + + var t1 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t1); + Assert.Equal("110101", t1[0].Code); + Assert.NotNull(t1[0].Parent); + Assert.Equal("110000", t1[0].Parent.Code); + + var t2 = fsql.Select() + .InnerJoin(a => a.ParentCode == a.Parent.Code) + .InnerJoin(a => a.Parent.ParentCode == a.Parent.Parent.Code) + .Where(a => a.Code == "110101") + .ToList(true); + Assert.Single(t2); + Assert.Equal("110101", t2[0].Code); + Assert.NotNull(t2[0].Parent); + Assert.Equal("110000", t2[0].Parent.Code); + Assert.NotNull(t2[0].Parent.Parent); + Assert.Equal("100000", t2[0].Parent.Parent.Code); + + var t3 = fsql.Select().ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToTreeList(); + Assert.Single(t3); + Assert.Equal("100000", t3[0].Code); + Assert.Single(t3[0].Childs); + Assert.Equal("110000", t3[0].Childs[0].Code); + Assert.Equal(2, t3[0].Childs[0].Childs.Count); + Assert.Equal("110100", t3[0].Childs[0].Childs[0].Code); + Assert.Equal("110101", t3[0].Childs[0].Childs[1].Code); + + t3 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte().OrderBy(a => a.Code).ToList(); + Assert.Equal(4, t3.Count); + Assert.Equal("100000", t3[0].Code); + Assert.Equal("110000", t3[1].Code); + Assert.Equal("110100", t3[2].Code); + Assert.Equal("110101", t3[3].Code); + + t3 = fsql.Select().Where(a => a.Name == "北京").AsTreeCte().OrderBy(a => a.Code).ToList(); + Assert.Equal(3, t3.Count); + Assert.Equal("110000", t3[0].Code); + Assert.Equal("110100", t3[1].Code); + Assert.Equal("110101", t3[2].Code); + + var t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name).OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国", t4[0].path); + Assert.Equal("中国 -> 北京", t4[1].path); + Assert.Equal("中国 -> 北京 -> 北京市", t4[2].path); + Assert.Equal("中国 -> 北京 -> 东城区", t4[3].path); + + t4 = fsql.Select().Where(a => a.Name == "中国").AsTreeCte(a => a.Name + "[" + a.Code + "]").OrderBy(a => a.Code) + .ToList(a => new { item = a, level = Convert.ToInt32("a.cte_level"), path = "a.cte_path" }); + Assert.Equal(4, t4.Count); + Assert.Equal("100000", t4[0].item.Code); + Assert.Equal("110000", t4[1].item.Code); + Assert.Equal("110100", t4[2].item.Code); + Assert.Equal("110101", t4[3].item.Code); + Assert.Equal("中国[100000]", t4[0].path); + Assert.Equal("中国[100000] -> 北京[110000]", t4[1].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 北京市[110100]", t4[2].path); + Assert.Equal("中国[100000] -> 北京[110000] -> 东城区[110101]", t4[3].path); + + var select = fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte() + //.OrderBy("a.cte_level desc") //递归层级 + ; + // var list = select.ToList(); //自己调试看查到的数据 + select.ToUpdate().Set(a => a.testint, 855).ExecuteAffrows(); + Assert.Equal(855, fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Distinct().First(a => a.testint)); + + Assert.Equal(4, select.ToDelete().ExecuteAffrows()); + Assert.False(fsql.Select() + .Where(a => a.Name == "中国") + .AsTreeCte().Any()); + } + + [Table(Name = "D_District")] + public class BaseDistrict + { + [Column(IsPrimary = true, StringLength = 6)] + public string Code { get; set; } + + [Column(StringLength = 20, IsNullable = false)] + public string Name { get; set; } + + [Column(StringLength = 6)] + public virtual string ParentCode { get; set; } + + public int testint { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Child : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public List Childs { get; set; } + } + [Table(Name = "D_District", DisableSyncStructure = true)] + public class VM_District_Parent : BaseDistrict + { + public override string ParentCode { get => base.ParentCode; set => base.ParentCode = value; } + + [Navigate(nameof(ParentCode))] + public VM_District_Parent Parent { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerUpdateTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerUpdateTest.cs new file mode 100644 index 00000000..d44637c9 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/Curd/SqlServerUpdateTest.cs @@ -0,0 +1,199 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServer +{ + [Collection("SqlServerCollection")] + public class SqlServerUpdateTest + { + IUpdate update => g.sqlserver.Update(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int? Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Fact] + public void Dywhere() + { + Assert.Null(g.sqlserver.Update().ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test' \r\nWHERE ([Id] IN (1,2))", g.sqlserver.Update(new[] { 1, 2 }).SetRaw("title='test'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] IN (1,2))", g.sqlserver.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").ToSql()); + Assert.Equal("UPDATE [tb_topic] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new { id = 1 }).SetRaw("title='test1'").ToSql()); + } + + [Fact] + public void SetSource() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = NULL, [Title] = N'newtitle', [CreateTime] = '1970-01-01 00:00:00.000' WHERE ([Id] = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + items[0].Clicks = null; + + sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = CASE [Id] WHEN 1 THEN NULL WHEN 2 THEN 100 WHEN 3 THEN 200 WHEN 4 THEN 300 WHEN 5 THEN 400 WHEN 6 THEN 500 WHEN 7 THEN 600 WHEN 8 THEN 700 WHEN 9 THEN 800 WHEN 10 THEN 900 END, [Title] = CASE [Id] WHEN 1 THEN N'newtitle0' WHEN 2 THEN N'newtitle1' WHEN 3 THEN N'newtitle2' WHEN 4 THEN N'newtitle3' WHEN 5 THEN N'newtitle4' WHEN 6 THEN N'newtitle5' WHEN 7 THEN N'newtitle6' WHEN 8 THEN N'newtitle7' WHEN 9 THEN N'newtitle8' WHEN 10 THEN N'newtitle9' END, [CreateTime] = CASE [Id] WHEN 1 THEN '1970-01-01 00:00:00.000' WHEN 2 THEN '1970-01-01 00:00:00.000' WHEN 3 THEN '1970-01-01 00:00:00.000' WHEN 4 THEN '1970-01-01 00:00:00.000' WHEN 5 THEN '1970-01-01 00:00:00.000' WHEN 6 THEN '1970-01-01 00:00:00.000' WHEN 7 THEN '1970-01-01 00:00:00.000' WHEN 8 THEN '1970-01-01 00:00:00.000' WHEN 9 THEN '1970-01-01 00:00:00.000' WHEN 10 THEN '1970-01-01 00:00:00.000' END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = CASE [Id] WHEN 1 THEN N'newtitle0' WHEN 2 THEN N'newtitle1' WHEN 3 THEN N'newtitle2' WHEN 4 THEN N'newtitle3' WHEN 5 THEN N'newtitle4' WHEN 6 THEN N'newtitle5' WHEN 7 THEN N'newtitle6' WHEN 8 THEN N'newtitle7' WHEN 9 THEN N'newtitle8' WHEN 10 THEN N'newtitle9' END WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = update.SetSource(items).IgnoreColumns(a => a.TypeGuid).Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [CreateTime] = '2020-01-01 00:00:00.000' WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + + sql = g.sqlserver.Update().SetSource(new[] { + new ts_source_mpk { id1 = 1, id2 = 7, xx = "a1" }, + new ts_source_mpk { id1 = 1, id2 = 8, xx = "b122" } + }).NoneParameter().ToSql().Replace("\r\n", ""); + } + public class ts_source_mpk + { + [Column(IsPrimary = true)] + public int id1 { get; set; } + [Column(IsPrimary = true)] + public int id2 { get; set; } + public string xx { get; set; } + } + [Fact] + public void SetSourceIgnore() + { + Assert.Equal("UPDATE [tssi01] SET [tint] = 10 WHERE ([id] = '00000000-0000-0000-0000-000000000000')", + g.sqlserver.Update().NoneParameter() + .SetSourceIgnore(new tssi01 { id = Guid.Empty, tint = 10 }, col => col == null).ToSql().Replace("\r\n", "")); + } + public class tssi01 + { + [Column(CanUpdate = false)] + public Guid id { get; set; } + public int tint { get; set; } + public string title { get; set; } + } + [Fact] + public void IgnoreColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).IgnoreColumns(a => new { a.Clicks, a.CreateTime, a.TypeGuid }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = N'newtitle' WHERE ([Id] = 1)", sql); + } + [Fact] + public void UpdateColumns() + { + var sql = update.SetSource(new Topic { Id = 1, Title = "newtitle" }).UpdateColumns(a => a.Title).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = N'newtitle' WHERE ([Id] = 1)", sql); + } + [Fact] + public void Set() + { + var sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = N'newtitle' WHERE ([Id] = 1)", sql); + + sql = update.Where(a => a.Id == 1).Set(a => a.Title, "newtitle").Set(a => a.CreateTime, new DateTime(2020, 1, 1)).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Title] = N'newtitle', [CreateTime] = '2020-01-01 00:00:00.000' WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = isnull([Clicks], 0) * 10 / 1 WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Id - 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Id] = ([Id] - 10) WHERE ([Id] = 1)", sql); + + int incrv = 10; + sql = update.Set(a => a.Clicks * incrv / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = isnull([Clicks], 0) * 10 / 1 WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Id - incrv).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Id] = ([Id] - 10) WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Clicks == a.Clicks * 10 / 1).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = [Clicks] * 10 / 1 WHERE ([Id] = 1)", sql); + + var dt2000 = DateTime.Parse("2000-01-01"); + sql = update.Set(a => a.Clicks == (a.CreateTime > dt2000 ? 1 : 2)).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = case when [CreateTime] > '2000-01-01 00:00:00.000' then 1 else 2 end WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Id == 10).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Id] = 10 WHERE ([Id] = 1)", sql); + + sql = update.Set(a => a.Clicks == null).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = NULL WHERE ([Id] = 1)", sql); + } + [Fact] + public void SetRaw() + { + var sql = update.Where(a => a.Id == 1).SetRaw("clicks = clicks + ?", new { incrClick = 1 }).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET clicks = clicks + ? WHERE ([Id] = 1)", sql); + } + [Fact] + public void SetDto() + { + var sql = update.SetDto(new { clicks = 1, title = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = 1, [Title] = N'xxx' WHERE ([Id] = 1)", sql); + + sql = update.SetDto(new Dictionary { ["clicks"] = 1, ["title"] = "xxx" }).Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET [Clicks] = 1, [Title] = N'xxx' WHERE ([Id] = 1)", sql); + } + [Fact] + public void Where() + { + var sql = update.Where(a => a.Id == 1).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] = 1)", sql); + + sql = update.Where("id = ?", new { id = 1 }).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE (id = ?)", sql); + + var item = new Topic { Id = 1, Title = "newtitle" }; + sql = update.Where(item).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] = 1)", sql); + + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + sql = update.Where(items).SetRaw("title='newtitle'").ToSql().Replace("\r\n", ""); + Assert.Equal("UPDATE [tb_topic] SET title='newtitle' WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); + } + [Fact] + public void ExecuteAffrows() + { + var items = new List(); + for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); + + var time = DateTime.Now; + var items222 = g.sqlserver.Select().Where(a => a.CreateTime > time).Limit(10).ToList(); + + update.SetSource(items.First()).NoneParameter().ExecuteAffrows(); + update.SetSource(items).NoneParameter().ExecuteAffrows(); + } + [Fact] + public void ExecuteUpdated() + { + g.sqlserver.Insert().AppendData(new Topic()).ExecuteAffrows(); + g.sqlserver.Insert().AppendData(new Topic()).ExecuteAffrows(); + g.sqlserver.Insert().AppendData(new Topic()).ExecuteAffrows(); + g.sqlserver.Insert().AppendData(new Topic()).ExecuteAffrows(); + + var items = g.sqlserver.Select().Limit(2).ToList(); + g.sqlserver.Update(items).SetRaw("Title='test'").ExecuteUpdated(); + + items = g.sqlserver.Select().Limit(2).ToList(); + var result = g.sqlserver.Update(items).SetRaw("Title='test'").ExecuteUpdatedAsync().Result; + } + + [Fact] + public void AsTable() + { + Assert.Null(g.sqlserver.Update().ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test' \r\nWHERE ([Id] IN (1,2))", g.sqlserver.Update(new[] { 1, 2 }).SetRaw("title='test'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new Topic { Id = 1, Title = "test" }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] IN (1,2))", g.sqlserver.Update(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + Assert.Equal("UPDATE [tb_topicAsTable] SET title='test1' \r\nWHERE ([Id] = 1)", g.sqlserver.Update(new { id = 1 }).SetRaw("title='test1'").AsTable(a => "tb_topicAsTable").ToSql()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/BoolNullableTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/BoolNullableTest.cs new file mode 100644 index 00000000..6b402b9f --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/BoolNullableTest.cs @@ -0,0 +1,1572 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServerMapType +{ + [Collection("SqlServerCollection")] + public class BoolNullableTest + { + class BoolNullableMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool))] + public bool? tobool { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool? tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool? tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool? toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool? toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool? toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool? tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool? tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool? tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool? tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool? tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool? toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool? toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool? touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool? touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool? toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool? toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool? tostring { get; set; } = true; + } + [Fact] + public void Bool() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item = new BoolNullableMap { tobool = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item = new BoolNullableMap { tobool = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update all + item.tobool = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(true, find.tobool); + + item.tobool = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + item.tobool = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobool, find.tobool); + Assert.Equal(false, find.tobool); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobool, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobool == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobool == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobool); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobool == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobool == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item = new BoolNullableMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item = new BoolNullableMap { tosbyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(true, find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + item.tosbyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tosbyte, find.tosbyte); + Assert.Equal(false, find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item = new BoolNullableMap { tosbytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(true, find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Equal(false, find.tosbytenullable); + + item.tosbytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.Null(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item = new BoolNullableMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item = new BoolNullableMap { toshort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(true, find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + item.toshort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toshort, find.toshort); + Assert.Equal(false, find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item = new BoolNullableMap { toshortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(true, find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Equal(false, find.toshortnullable); + + item.toshortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.Null(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item = new BoolNullableMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item = new BoolNullableMap { toint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(true, find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.Equal(false, find.toint); + + item.toint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toint, find.toint); + Assert.Equal(false, find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item = new BoolNullableMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item = new BoolNullableMap { tointnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(true, find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Equal(false, find.tointnullable); + + item.tointnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.Null(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item = new BoolNullableMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item = new BoolNullableMap { tolong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(true, find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + item.tolong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tolong, find.tolong); + Assert.Equal(false, find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item = new BoolNullableMap { tolongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(true, find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Equal(false, find.tolongnullable); + + item.tolongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.Null(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item = new BoolNullableMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item = new BoolNullableMap { tobyte = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(true, find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + item.tobyte = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.tobyte, find.tobyte); + Assert.Equal(false, find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobyte == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item = new BoolNullableMap { tobytenullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(true, find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Equal(false, find.tobytenullable); + + item.tobytenullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.Null(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item = new BoolNullableMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item = new BoolNullableMap { toushort = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(true, find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + item.toushort = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toushort, find.toushort); + Assert.Equal(false, find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushort == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item = new BoolNullableMap { toushortnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(true, find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Equal(false, find.toushortnullable); + + item.toushortnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.Null(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item = new BoolNullableMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item = new BoolNullableMap { touint = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(true, find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.Equal(false, find.touint); + + item.touint = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.touint, find.touint); + Assert.Equal(false, find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touint == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item = new BoolNullableMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item = new BoolNullableMap { touintnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(true, find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Equal(false, find.touintnullable); + + item.touintnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.Null(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item = new BoolNullableMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item = new BoolNullableMap { toulong = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(true, find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + item.toulong = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.NotEqual(item.toulong, find.toulong); + Assert.Equal(false, find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulong == null).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == null).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item = new BoolNullableMap { toulongnullable = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(true, find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Equal(false, find.toulongnullable); + + item.toulongnullable = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.Null(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == null).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.sqlserver; + var item = new BoolNullableMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item = new BoolNullableMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item = new BoolNullableMap { tostring = null }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(true, find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Equal(false, find.tostring); + + item.tostring = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.Null(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(true, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(false, find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.tostring == false).First()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/BoolTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/BoolTest.cs new file mode 100644 index 00000000..181187a1 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/BoolTest.cs @@ -0,0 +1,1105 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServerMapType +{ + [Collection("SqlServerCollection")] + public class BoolTest + { + class BoolMap + { + public Guid id { get; set; } + [Column(MapType = typeof(bool?))] + public bool toboolnullable { get; set; } = true; + + [Column(MapType = typeof(sbyte))] + public bool tosbyte { get; set; } = true; + [Column(MapType = typeof(sbyte?))] + public bool tosbytenullable { get; set; } = true; + + [Column(MapType = typeof(short))] + public bool toshort { get; set; } = true; + + [Column(MapType = typeof(short?))] + public bool toshortnullable { get; set; } = true; + + [Column(MapType = typeof(int))] + public bool toint { get; set; } = true; + + [Column(MapType = typeof(int?))] + public bool tointnullable { get; set; } = true; + + [Column(MapType = typeof(long))] + public bool tolong { get; set; } = true; + [Column(MapType = typeof(long?))] + public bool tolongnullable { get; set; } = true; + + [Column(MapType = typeof(byte))] + public bool tobyte { get; set; } = true; + [Column(MapType = typeof(byte?))] + public bool tobytenullable { get; set; } = true; + + [Column(MapType = typeof(ushort))] + public bool toushort { get; set; } = true; + + [Column(MapType = typeof(ushort?))] + public bool toushortnullable { get; set; } = true; + + [Column(MapType = typeof(uint))] + public bool touint { get; set; } = true; + + [Column(MapType = typeof(uint?))] + public bool touintnullable { get; set; } = true; + + [Column(MapType = typeof(ulong))] + public bool toulong { get; set; } = true; + [Column(MapType = typeof(ulong?))] + public bool toulongnullable { get; set; } = true; + + [Column(MapType = typeof(string))] + public bool tostring { get; set; } = true; + } + + [Fact] + public void BoolNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item = new BoolMap { toboolnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update all + item.toboolnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.True(find.toboolnullable); + + item.toboolnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toboolnullable, find.toboolnullable); + Assert.False(find.toboolnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toboolnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toboolnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toboolnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toboolnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toboolnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByte() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item = new BoolMap { tosbyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update all + item.tosbyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.True(find.tosbyte); + + item.tosbyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbyte, find.tosbyte); + Assert.False(find.tosbyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void SByteNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item = new BoolMap { tosbytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update all + item.tosbytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.True(find.tosbytenullable); + + item.tosbytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tosbytenullable, find.tosbytenullable); + Assert.False(find.tosbytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tosbytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tosbytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tosbytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tosbytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tosbytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Short() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item = new BoolMap { toshort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update all + item.toshort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.True(find.toshort); + + item.toshort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshort, find.toshort); + Assert.False(find.toshort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ShortNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item = new BoolMap { toshortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update all + item.toshortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.True(find.toshortnullable); + + item.toshortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toshortnullable, find.toshortnullable); + Assert.False(find.toshortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toshortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toshortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toshortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toshortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toshortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Int() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item = new BoolMap { toint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update all + item.toint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.True(find.toint); + + item.toint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toint, find.toint); + Assert.False(find.toint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void IntNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item = new BoolMap { tointnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update all + item.tointnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.True(find.tointnullable); + + item.tointnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tointnullable, find.tointnullable); + Assert.False(find.tointnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tointnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tointnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tointnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tointnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tointnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tointnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void Long() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item = new BoolMap { tolong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update all + item.tolong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.True(find.tolong); + + item.tolong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolong, find.tolong); + Assert.False(find.tolong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void LongNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item = new BoolMap { tolongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update all + item.tolongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.True(find.tolongnullable); + + item.tolongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tolongnullable, find.tolongnullable); + Assert.False(find.tolongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tolongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tolongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tolongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tolongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tolongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Byte() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item = new BoolMap { tobyte = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update all + item.tobyte = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.True(find.tobyte); + + item.tobyte = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobyte, find.tobyte); + Assert.False(find.tobyte); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobyte); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobyte, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobyte == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobyte); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobyte == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobyte == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ByteNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item = new BoolMap { tobytenullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update all + item.tobytenullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.True(find.tobytenullable); + + item.tobytenullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tobytenullable, find.tobytenullable); + Assert.False(find.tobytenullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tobytenullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tobytenullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tobytenullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tobytenullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tobytenullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShort() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item = new BoolMap { toushort = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update all + item.toushort = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.True(find.toushort); + + item.toushort = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushort, find.toushort); + Assert.False(find.toushort); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushort); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushort, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushort == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushort); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushort == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushort == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UShortNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item = new BoolMap { toushortnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update all + item.toushortnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.True(find.toushortnullable); + + item.toushortnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toushortnullable, find.toushortnullable); + Assert.False(find.toushortnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toushortnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toushortnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toushortnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toushortnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toushortnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UInt() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item = new BoolMap { touint = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update all + item.touint = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.True(find.touint); + + item.touint = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touint, find.touint); + Assert.False(find.touint); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touint); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touint, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touint == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touint); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touint == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touint == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void UIntNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item = new BoolMap { touintnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update all + item.touintnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.True(find.touintnullable); + + item.touintnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.touintnullable, find.touintnullable); + Assert.False(find.touintnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.touintnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.touintnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.touintnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.touintnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.touintnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.touintnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULong() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item = new BoolMap { toulong = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update all + item.toulong = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.True(find.toulong); + + item.toulong = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulong, find.toulong); + Assert.False(find.toulong); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulong); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulong, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulong == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulong); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulong == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulong == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void ULongNullable() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item = new BoolMap { toulongnullable = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update all + item.toulongnullable = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.True(find.toulongnullable); + + item.toulongnullable = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.toulongnullable, find.toulongnullable); + Assert.False(find.toulongnullable); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.toulongnullable); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.toulongnullable, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.toulongnullable == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.toulongnullable); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.toulongnullable == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void TimeSpan() + { + } + [Fact] + public void TimeSpanNullable() + { + } + [Fact] + public void DateTime() + { + } + [Fact] + public void DateTimeNullable() + { + } + + [Fact] + public void ByteArray() + { + } + [Fact] + public void String() + { + //insert + var orm = g.sqlserver; + var item = new BoolMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item = new BoolMap { tostring = false }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update all + item.tostring = true; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.True(find.tostring); + + item.tostring = false; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.tostring, find.tostring); + Assert.False(find.tostring); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, true).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == true).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.True(find.tostring); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.tostring, false).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.tostring == false).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.False(find.tostring); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.tostring == true).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.tostring == false).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid() + { + } + [Fact] + public void GuidNullable() + { + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/DateTimeOffSetTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/DateTimeOffSetTest.cs new file mode 100644 index 00000000..4af65bdf --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/DateTimeOffSetTest.cs @@ -0,0 +1,54 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServerMapType +{ + public class DateTimeOffSetTest + { + class DateTimeOffSetTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(DateTime))] + public DateTimeOffset dtos_to_dt { get; set; } + [Column(MapType = typeof(DateTime))] + public DateTimeOffset? dtosnullable_to_dt { get; set; } + } + [Fact] + public void DateTimeToDateTimeOffSet() + { + //insert + var orm = g.sqlserver; + var item = new DateTimeOffSetTestMap { dtos_to_dt = DateTimeOffset.Now, dtosnullable_to_dt = DateTimeOffset.Now }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update all + item.dtos_to_dt = DateTimeOffset.Now; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.dtos_to_dt, item.dtos_to_dt = DateTimeOffset.Now).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.dtos_to_dt.ToString("g"), find.dtos_to_dt.ToString("g")); + Assert.Equal(item.dtosnullable_to_dt.Value.ToString("g"), find.dtosnullable_to_dt.Value.ToString("g")); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/EnumTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/EnumTest.cs new file mode 100644 index 00000000..d8e1715d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/EnumTest.cs @@ -0,0 +1,263 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServerMapType +{ + [Collection("SqlServerCollection")] + public class EnumTest + { + + class EnumTestMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(int))] + public ToStringMapEnum enum_to_int { get; set; } + [Column(MapType = typeof(int?))] + public ToStringMapEnum? enumnullable_to_int { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void EnumToString() + { + //insert + var orm = g.sqlserver; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new EnumTestMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToString() + { + //insert + var orm = g.sqlserver; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new EnumTestMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void EnumToInt() + { + //insert + var orm = g.sqlserver; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + item = new EnumTestMap { enum_to_int = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //update all + item.enum_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + item.enum_to_int = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_int, find.enum_to_int); + Assert.Equal(ToStringMapEnum.й, find.enum_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_int); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_int == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullableToInt() + { + //insert + var orm = g.sqlserver; + var item = new EnumTestMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + item = new EnumTestMap { enumnullable_to_int = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_int); + + //update all + item.enumnullable_to_int = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_int); + + item.enumnullable_to_int = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_int, find.enumnullable_to_int); + Assert.Null(find.enumnullable_to_int); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_int); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_int, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_int == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_int); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_int == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/ToStringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/ToStringTest.cs new file mode 100644 index 00000000..bd9dd521 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/MapType/ToStringTest.cs @@ -0,0 +1,571 @@ +using FreeSql.DataAnnotations; +using System; +using System.Numerics; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServerMapType +{ + [Collection("SqlServerCollection")] + public class ToStringTest + { + class ToStringMap + { + public Guid id { get; set; } + + [Column(MapType = typeof(string))] + public TimeSpan timespan_to_string { get; set; } + [Column(MapType = typeof(string))] + public TimeSpan? timespannullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public DateTime datetime_to_string { get; set; } + [Column(MapType = typeof(string))] + public DateTime? datetimenullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public Guid guid_to_string { get; set; } + [Column(MapType = typeof(string))] + public Guid? guidnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public ToStringMapEnum enum_to_string { get; set; } + [Column(MapType = typeof(string))] + public ToStringMapEnum? enumnullable_to_string { get; set; } + + [Column(MapType = typeof(string))] + public BigInteger biginteger_to_string { get; set; } + [Column(MapType = typeof(string))] + public BigInteger? bigintegernullable_to_string { get; set; } + } + public enum ToStringMapEnum { й, abc, } + [Fact] + public void Enum1() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + item = new ToStringMap { enum_to_string = ToStringMapEnum.abc }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //update all + item.enum_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + item.enum_to_string = ToStringMapEnum.й; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enum_to_string, find.enum_to_string); + Assert.Equal(ToStringMapEnum.й, find.enum_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum., find.enum_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enum_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enum_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enum_to_string == ToStringMapEnum.abc).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void EnumNullable() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + item = new ToStringMap { enumnullable_to_string = ToStringMapEnum.й }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum.й, find.enumnullable_to_string); + + //update all + item.enumnullable_to_string = ToStringMapEnum.; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Equal(ToStringMapEnum., find.enumnullable_to_string); + + item.enumnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.enumnullable_to_string, find.enumnullable_to_string); + Assert.Null(find.enumnullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, ToStringMapEnum.abc).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(ToStringMapEnum.abc, find.enumnullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.enumnullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.abc).First()); + find = orm.Select().Where(a => a.id == item.id && a.enumnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.enumnullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.й).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == ToStringMapEnum.).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.enumnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigInteger1() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 0).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(0, find.biginteger_to_string); + + item = new ToStringMap { biginteger_to_string = 100 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 100).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(100, find.biginteger_to_string); + + //update all + item.biginteger_to_string = 200; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 200).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(200, find.biginteger_to_string); + + item.biginteger_to_string = 205; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 205).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.biginteger_to_string, find.biginteger_to_string); + Assert.Equal(205, find.biginteger_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 522).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 522).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(522, find.biginteger_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.biginteger_to_string, 10005).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.biginteger_to_string == 10005).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(10005, find.biginteger_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 522).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 205).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.biginteger_to_string == 10005).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void BigIntegerNullable() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + item = new ToStringMap { bigintegernullable_to_string = 101 }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 101).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(101, find.bigintegernullable_to_string); + + //update all + item.bigintegernullable_to_string = 2004; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Equal(2004, find.bigintegernullable_to_string); + + item.bigintegernullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.bigintegernullable_to_string, find.bigintegernullable_to_string); + Assert.Null(find.bigintegernullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, 998).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(998, find.bigintegernullable_to_string); + + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.bigintegernullable_to_string, null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).First()); + find = orm.Select().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.bigintegernullable_to_string); + + //delete + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 998).ExecuteAffrows()); + Assert.Equal(0, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == 2004).ExecuteAffrows()); + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.bigintegernullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpan1() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.Zero, find.timespan_to_string); + + item = new ToStringMap { timespan_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespan_to_string); + + //update all + item.timespan_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespan_to_string, find.timespan_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespan_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespan_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespan_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void TimeSpanNullable() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + item = new ToStringMap { timespannullable_to_string = TimeSpan.FromDays(1) }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromDays(1), find.timespannullable_to_string); + + //update all + item.timespannullable_to_string = TimeSpan.FromHours(10); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Equal(TimeSpan.FromHours(10), find.timespannullable_to_string); + + item.timespannullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.timespannullable_to_string, find.timespannullable_to_string); + Assert.Null(find.timespannullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, TimeSpan.FromHours(11)).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(TimeSpan.FromHours(11), find.timespannullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.timespannullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.timespannullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTime1() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.MinValue, find.datetime_to_string); + + item = new ToStringMap { datetime_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetime_to_string); + + //update all + item.datetime_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetime_to_string, find.datetime_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetime_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetime_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetime_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void DateTimeNullable() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + item = new ToStringMap { datetimenullable_to_string = DateTime.Parse("2000-1-1") }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-1"), find.datetimenullable_to_string); + + //update all + item.datetimenullable_to_string = DateTime.Parse("2000-1-11"); + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Equal(DateTime.Parse("2000-1-11"), find.datetimenullable_to_string); + + item.datetimenullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.datetimenullable_to_string, find.datetimenullable_to_string); + Assert.Null(find.datetimenullable_to_string); + + //update set + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, DateTime.Parse("2000-1-12")).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(DateTime.Parse("2000-1-12"), find.datetimenullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.datetimenullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.datetimenullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + + [Fact] + public void Guid1() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == Guid.Empty).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(Guid.Empty, find.guid_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guid_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update all + newid = Guid.NewGuid(); + item.guid_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guid_to_string, find.guid_to_string); + Assert.Equal(newid, find.guid_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guid_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guid_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guid_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guid_to_string == newid).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + [Fact] + public void GuidNullable() + { + //insert + var orm = g.sqlserver; + var item = new ToStringMap { }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + var find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + var newid = Guid.NewGuid(); + item = new ToStringMap { guidnullable_to_string = newid }; + Assert.Equal(1, orm.Insert().AppendData(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + //update all + newid = Guid.NewGuid(); + item.guidnullable_to_string = newid; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Equal(newid, find.guidnullable_to_string); + + item.guidnullable_to_string = null; + Assert.Equal(1, orm.Update().SetSource(item).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(item.guidnullable_to_string, find.guidnullable_to_string); + Assert.Null(find.guidnullable_to_string); + + //update set + newid = Guid.NewGuid(); + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, newid).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == newid).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal(newid, find.guidnullable_to_string); + + Assert.Equal(1, orm.Update().Where(a => a.id == item.id).Set(a => a.guidnullable_to_string, null).ExecuteAffrows()); + find = orm.Select().Where(a => a.id == item.id && a.guidnullable_to_string == null).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Null(find.guidnullable_to_string); + + //delete + Assert.Equal(1, orm.Delete().Where(a => a.id == item.id && a.guidnullable_to_string == null).ExecuteAffrows()); + Assert.Null(orm.Select().Where(a => a.id == item.id).First()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerAdo/SqlServerAdoTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerAdo/SqlServerAdoTest.cs new file mode 100644 index 00000000..5ce08874 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerAdo/SqlServerAdoTest.cs @@ -0,0 +1,98 @@ +using FreeSql.DataAnnotations; +using System; +using System.Data.Odbc; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServer +{ + [Collection("SqlServerCollection")] + public class SqlServerAdoTest + { + [Fact] + public void Pool() + { + var t1 = g.sqlserver.Ado.MasterPool.StatisticsFullily; + } + + [Fact] + public void SlavePools() + { + var t2 = g.sqlserver.Ado.SlavePools.Count; + } + + [Fact] + public void ExecuteTest() + { + Assert.True(g.sqlserver.Ado.ExecuteConnectTest()); + } + [Fact] + public void ExecuteReader() + { + + } + [Fact] + public void ExecuteArray() + { + + } + [Fact] + public void ExecuteNonQuery() + { + + } + [Fact] + public void ExecuteScalar() + { + + } + + [Fact] + public void Query() + { + + //var tt1 = g.sqlserver.Select() + // .LeftJoin(a => a.ParentId == a.Parent.Id) + // .ToSql(a => new { a.Id, a.Title }); + + //var tt2result = g.sqlserver.Select() + // .LeftJoin(a => a.ParentId == a.Parent.Id) + // .ToList(a => new { a.Id, a.Title }); + + //var tt = g.sqlserver.Select() + // .LeftJoin((a, b) => b.Id == a.Id) + // .ToSql(a => new { a.Id, a.Title }); + + //var ttresult = g.sqlserver.Select() + // .LeftJoin((a, b) => b.Id == a.Id) + // .ToList(a => new { a.Id, a.Title }); + + var tnsql1 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToSql(a => a.Id); + var tnsql2 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(2, 3).ToSql(a => a.Id); + + var tn1 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToList(a => a.Id); + var tn2 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(2, 3).ToList(a => a.Id); + + var t3 = g.sqlserver.Ado.Query("select * from xxx"); + + var t4 = g.sqlserver.Ado.Query<(int, int, string, string DateTime)>("select * from xxx"); + } + + [Fact] + public void QueryMultipline() + { + var tnsql1 = g.sqlserver.Select().Where(a => a.Id > 0).Where(b => b.Title != null).Page(1, 3).ToSql(a => a.Id); + + var t3 = g.sqlserver.Ado.Query("select * from xxx; select * from xxx; select * from xxx"); + } + + class xxx + { + public int Id { get; set; } + public int ParentId { get; set; } + public xxx Parent { get; set; } + public string Title { get; set; } + public string Url { get; set; } + public DateTime Create_time { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerAopTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerAopTest.cs new file mode 100644 index 00000000..85381754 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerAopTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServer +{ + public class SqlServerAopTest + { + + class TestAuditValue + { + public Guid id { get; set; } + [Now] + public DateTime createtime { get; set; } + } + class NowAttribute: Attribute { } + + [Fact] + public void AuditValue() + { + var date = DateTime.Now.Date; + var item = new TestAuditValue(); + + EventHandler audit = (s, e) => + { + if (e.Property.GetCustomAttribute(false) != null) + e.Value = DateTime.Now.Date; + }; + g.sqlserver.Aop.AuditValue += audit; + + g.sqlserver.Insert(item).ExecuteAffrows(); + + g.sqlserver.Aop.AuditValue -= audit; + + Assert.Equal(item.createtime, date); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerCodeFirstTest.cs new file mode 100644 index 00000000..3815053d --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerCodeFirstTest.cs @@ -0,0 +1,485 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServer +{ + + [Collection("SqlServerCollection")] + public class SqlServerCodeFirstTest + { + [Fact] + public void Test_0String() + { + var fsql = g.sqlserver; + fsql.Delete().Where("1=1").ExecuteAffrows(); + + Assert.Equal(1, fsql.Insert(new test_0string01 { name = @"1.0000\0.0000\0.0000\0.0000\1.0000\0.0000" }).ExecuteAffrows()); + Assert.Equal(1, fsql.Insert(new test_0string01 { name = @"1.0000\0.0000\0.0000\0.0000\1.0000\0.0000" }).NoneParameter().ExecuteAffrows()); + + var list = fsql.Select().ToList(); + Assert.Equal(2, list.Count); + Assert.Equal(@"1.0000\0.0000\0.0000\0.0000\1.0000\0.0000", list[0].name); + Assert.Equal(@"1.0000\0.0000\0.0000\0.0000\1.0000\0.0000", list[1].name); + } + class test_0string01 + { + public Guid id { get; set; } + public string name { get; set; } + } + + [Fact] + public void StringLength() + { + var dll = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); + g.sqlserver.CodeFirst.SyncStructure(); + } + class TS_SLTB + { + public Guid Id { get; set; } + [Column(StringLength = 50)] + public string Title { get; set; } + + [Column(IsNullable = false, StringLength = 50)] + public string TitleSub { get; set; } + } + + [Fact] + public void 表名中有点() + { + var item = new tbdot01 { name = "insert" }; + g.sqlserver.Insert(item).ExecuteAffrows(); + + var find = g.sqlserver.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal("insert", find.name); + + Assert.Equal(1, g.sqlserver.Update().Set(a => a.name == "update").Where(a => a.id == item.id).ExecuteAffrows()); + find = g.sqlserver.Select().Where(a => a.id == item.id).First(); + Assert.NotNull(find); + Assert.Equal(item.id, find.id); + Assert.Equal("update", find.name); + + Assert.Equal(1, g.sqlserver.Delete().Where(a => a.id == item.id).ExecuteAffrows()); + find = g.sqlserver.Select().Where(a => a.id == item.id).First(); + Assert.Null(find); + } + /// + /// 表中带点 + /// + [Table(Name = "[freesql.T].[dbo].[sys.tbdot01]")] + class tbdot01 + { + /// + /// 主键 + /// + public Guid id { get; set; } + public string name { get; set; } + } + + [Fact] + public void 中文表_字段() + { + var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements<测试中文表>(); + g.sqlserver.CodeFirst.SyncStructure<测试中文表>(); + + var item = new 测试中文表 + { + 标题 = "测试标题", + 创建时间 = DateTime.Now + }; + Assert.Equal(1, g.sqlserver.Insert<测试中文表>().AppendData(item).ExecuteAffrows()); + Assert.NotEqual(Guid.Empty, item.编号); + var item2 = g.sqlserver.Select<测试中文表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新"; + Assert.Equal(1, g.sqlserver.Update<测试中文表>().SetSource(item).ExecuteAffrows()); + item2 = g.sqlserver.Select<测试中文表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新_repo"; + var repo = g.sqlserver.GetRepository<测试中文表>(); + Assert.Equal(1, repo.Update(item)); + item2 = g.sqlserver.Select<测试中文表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + + item.标题 = "测试标题更新_repo22"; + Assert.Equal(1, repo.Update(item)); + item2 = g.sqlserver.Select<测试中文表>().Where(a => a.编号 == item.编号).First(); + Assert.NotNull(item2); + Assert.Equal(item.编号, item2.编号); + Assert.Equal(item.标题, item2.标题); + } + class 测试中文表 + { + [Column(IsPrimary = true)] + public Guid 编号 { get; set; } + + public string 标题 { get; set; } + + public DateTime 创建时间 { get; set; } + } + + + [Fact] + public void AddUniques() + { + var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); + g.sqlserver.CodeFirst.SyncStructure(); + g.sqlserver.CodeFirst.SyncStructure(typeof(AddUniquesInfo), "AddUniquesInfo1"); + } + [Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")] + [Index("uk_phone", "phone", true)] + [Index("uk_group_index", "group,index", true)] + [Index("uk_group_index22", "group, index22", true)] + class AddUniquesInfo + { + public Guid id { get; set; } + public string phone { get; set; } + + public string group { get; set; } + public int index { get; set; } + public string index22 { get; set; } + } + + [Fact] + public void AddField() + { + var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); + + 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; } + + 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"; + + [Column(IsIgnore = true)] + public DateTime ct { get; set; } = DateTime.Now; + } + + [Fact] + public void GetComparisonDDLStatements() + { + var sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); + Assert.True(string.IsNullOrEmpty(sql)); //测试运行两次后 + sql = g.sqlserver.CodeFirst.GetComparisonDDLStatements(); + } + + IInsert insert => g.sqlserver.Insert(); + ISelect select => g.sqlserver.Select(); + + [Fact] + public void CurdAllField() + { + var item = new TableAllType { }; + item.Id = (int)insert.AppendData(item).ExecuteIdentity(); + + var newitem = select.Where(a => a.Id == item.Id).ToOne(); + + var item2 = new TableAllType + { + testFieldBool = true, + testFieldBoolNullable = true, + testFieldByte = byte.MaxValue, + testFieldByteNullable = byte.MinValue, + testFieldBytes = Encoding.UTF8.GetBytes("我是中国人"), + testFieldDateTime = DateTime.Now, + testFieldDateTimeNullable = DateTime.Now.AddHours(1), + testFieldDateTimeNullableOffset = new DateTimeOffset(DateTime.Now.AddHours(1), TimeSpan.FromHours(8)), + testFieldDateTimeOffset = new DateTimeOffset(DateTime.Now, TimeSpan.FromHours(8)), + testFieldDecimal = 998.99M, + testFieldDecimalNullable = 999.12M, + testFieldDouble = 99.199, + testFieldDoubleNullable = 99.211, + testFieldEnum1 = TableAllTypeEnumType1.e2, + testFieldEnum1Nullable = TableAllTypeEnumType1.e3, + testFieldEnum2 = TableAllTypeEnumType2.f3, + testFieldEnum2Nullable = TableAllTypeEnumType2.f2, + testFieldFloat = 0.99F, + testFieldFloatNullable = 0.11F, + testFieldGuid = Guid.NewGuid(), + testFieldGuidNullable = Guid.NewGuid(), + testFieldInt = int.MaxValue, + testFieldIntNullable = int.MinValue, + testFieldLong = long.MaxValue, + testFieldSByte = sbyte.MaxValue, + testFieldSByteNullable = sbyte.MinValue, + testFieldShort = short.MaxValue, + testFieldShortNullable = short.MinValue, + testFieldString = "我是中国人string'\\?!@#$%^&*()_+{}}{~?><<>", + testFieldChar = 'X', + testFieldTimeSpan = TimeSpan.FromSeconds(999), + testFieldTimeSpanNullable = TimeSpan.FromSeconds(30), + testFieldUInt = uint.MaxValue, + testFieldUIntNullable = uint.MinValue, + testFieldULong = ulong.MaxValue, + testFieldULongNullable = ulong.MinValue, + testFieldUShort = ushort.MaxValue, + testFieldUShortNullable = ushort.MinValue, + testFielLongNullable = long.MinValue + }; + + var sqlPar = insert.AppendData(item2).ToSql(); + var sqlText = insert.AppendData(item2).NoneParameter().ToSql(); + var item3NP = insert.AppendData(item2).NoneParameter().ExecuteInserted(); + + var sqlTestUpdate = g.sqlserver.Update().SetSource(item3NP).NoneParameter().ToSql(); + + var item3 = insert.AppendData(item2).ExecuteInserted(); + var newitem2 = select.Where(a => a.Id == item3[0].Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); + + item3 = insert.NoneParameter().AppendData(item2).ExecuteInserted(); + newitem2 = select.Where(a => a.Id == item3[0].Id).ToOne(); + Assert.Equal(item2.testFieldString, newitem2.testFieldString); + Assert.Equal(item2.testFieldChar, newitem2.testFieldChar); + + var items = select.ToList(); + var itemstb = select.ToDataTable(); + } + + [JsonObject(MemberSerialization.OptIn), Table(Name = "dbo.tb_alltype")] + public partial class Tb_alltype + { + + [JsonProperty, Column(Name = "Id", DbType = "int", IsPrimary = true, IsIdentity = true)] + public int Id { get; set; } + + + [JsonProperty, Column(Name = "testFieldBool1111", DbType = "bit")] + public bool TestFieldBool1111 { get; set; } + + + [JsonProperty, Column(Name = "testFieldBoolNullable", DbType = "bit", IsNullable = true)] + public bool? TestFieldBoolNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldByte", DbType = "tinyint")] + public sbyte TestFieldByte { get; set; } + + + [JsonProperty, Column(Name = "testFieldByteNullable", DbType = "tinyint", IsNullable = true)] + public sbyte? TestFieldByteNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldBytes", DbType = "varbinary(255)", IsNullable = true)] + public byte[] TestFieldBytes { get; set; } + + + [JsonProperty, Column(Name = "testFieldDateTime", DbType = "datetime")] + public DateTime TestFieldDateTime { get; set; } + + + [JsonProperty, Column(Name = "testFieldDateTimeNullable", DbType = "datetime", IsNullable = true)] + public DateTime? TestFieldDateTimeNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldDateTimeNullableOffset", DbType = "datetimeoffset", IsNullable = true)] + public DateTime? TestFieldDateTimeNullableOffset { get; set; } + + + [JsonProperty, Column(Name = "testFieldDateTimeOffset", DbType = "datetimeoffset")] + public DateTime TestFieldDateTimeOffset { get; set; } + + + [JsonProperty, Column(Name = "testFieldDecimal", DbType = "decimal(10,2)")] + public decimal TestFieldDecimal { get; set; } + + + [JsonProperty, Column(Name = "testFieldDecimalNullable", DbType = "decimal(10,2)", IsNullable = true)] + public decimal? TestFieldDecimalNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldDouble", DbType = "float")] + public double TestFieldDouble { get; set; } + + + [JsonProperty, Column(Name = "testFieldDoubleNullable", DbType = "float", IsNullable = true)] + public double? TestFieldDoubleNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum1", DbType = "int")] + public int TestFieldEnum1 { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum1Nullable", DbType = "int", IsNullable = true)] + public int? TestFieldEnum1Nullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum2", DbType = "bigint")] + public long TestFieldEnum2 { get; set; } + + + [JsonProperty, Column(Name = "testFieldEnum2Nullable", DbType = "bigint", IsNullable = true)] + public long? TestFieldEnum2Nullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldFloat", DbType = "real")] + public float TestFieldFloat { get; set; } + + + [JsonProperty, Column(Name = "testFieldFloatNullable", DbType = "real", IsNullable = true)] + public float? TestFieldFloatNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldGuid", DbType = "uniqueidentifier")] + public Guid TestFieldGuid { get; set; } + + + [JsonProperty, Column(Name = "testFieldGuidNullable", DbType = "uniqueidentifier", IsNullable = true)] + public Guid? TestFieldGuidNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldInt", DbType = "int")] + public int TestFieldInt { get; set; } + + + [JsonProperty, Column(Name = "testFieldIntNullable", DbType = "int", IsNullable = true)] + public int? TestFieldIntNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldLong", DbType = "bigint")] + public long TestFieldLong { get; set; } + + + [JsonProperty, Column(Name = "testFieldSByte", DbType = "tinyint")] + public sbyte TestFieldSByte { get; set; } + + + [JsonProperty, Column(Name = "testFieldSByteNullable", DbType = "tinyint", IsNullable = true)] + public sbyte? TestFieldSByteNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldShort", DbType = "smallint")] + public short TestFieldShort { get; set; } + + + [JsonProperty, Column(Name = "testFieldShortNullable", DbType = "smallint", IsNullable = true)] + public short? TestFieldShortNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldString", DbType = "nvarchar(255)", IsNullable = true)] + public string TestFieldString { get; set; } + + + [JsonProperty, Column(Name = "testFieldChar", DbType = "char(1)", IsNullable = true)] + public char testFieldChar { get; set; } + + + [JsonProperty, Column(Name = "testFieldTimeSpan", DbType = "time")] + public TimeSpan TestFieldTimeSpan { get; set; } + + + [JsonProperty, Column(Name = "testFieldTimeSpanNullable", DbType = "time", IsNullable = true)] + public TimeSpan? TestFieldTimeSpanNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldUInt", DbType = "int")] + public int TestFieldUInt { get; set; } + + + [JsonProperty, Column(Name = "testFieldUIntNullable", DbType = "int", IsNullable = true)] + public int? TestFieldUIntNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldULong", DbType = "bigint")] + public long TestFieldULong { get; set; } + + + [JsonProperty, Column(Name = "testFieldULongNullable", DbType = "bigint", IsNullable = true)] + public long? TestFieldULongNullable { get; set; } + + + [JsonProperty, Column(Name = "testFieldUShort", DbType = "smallint")] + public short TestFieldUShort { get; set; } + + + [JsonProperty, Column(Name = "testFieldUShortNullable", DbType = "smallint", IsNullable = true)] + public short? TestFieldUShortNullable { get; set; } + + + [JsonProperty, Column(Name = "testFielLongNullable", DbType = "bigint", IsNullable = true)] + public long? TestFielLongNullable { get; set; } + } + + [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 char testFieldChar { 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/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerDbFirstTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerDbFirstTest.cs new file mode 100644 index 00000000..bfa499ad --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerDbFirstTest.cs @@ -0,0 +1,65 @@ +using FreeSql.DataAnnotations; +using System; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServer +{ + [Collection("SqlServerCollection")] + public class SqlServerDbFirstTest + { + [Fact] + public void GetDatabases() + { + var t1 = g.sqlserver.DbFirst.GetDatabases(); + } + + [Fact] + public void GetTablesByDatabase() + { + var t2 = g.sqlserver.DbFirst.GetTablesByDatabase(); + Assert.True(t2.Count > 0); + } + + [Fact] + public void GetTableByName() + { + var fsql = g.sqlserver; + var t1 = fsql.DbFirst.GetTableByName("tb_alltype"); + var t2 = fsql.DbFirst.GetTableByName("dbo.tb_alltype"); + Assert.NotNull(t1); + Assert.NotNull(t2); + Assert.True(t1.Columns.Count > 0); + Assert.True(t2.Columns.Count > 0); + Assert.Equal(t1.Columns.Count, t2.Columns.Count); + var t3 = fsql.DbFirst.GetTableByName("notexists_tb"); + Assert.Null(t3); + } + + [Fact] + public void ExistsTable() + { + var fsql = g.sqlserver; + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("dbo.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("test_existstb01", false)); + Assert.False(fsql.DbFirst.ExistsTable("dbo.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01)); + Assert.True(fsql.DbFirst.ExistsTable("test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("dbo.test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("Test_existstb01", false)); + Assert.True(fsql.DbFirst.ExistsTable("dbo.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table test_existstb01"); + + Assert.False(fsql.DbFirst.ExistsTable("xxxtb.test_existstb01")); + Assert.False(fsql.DbFirst.ExistsTable("xxxtb.test_existstb01", false)); + fsql.CodeFirst.SyncStructure(typeof(test_existstb01), "xxxtb.test_existstb01"); + Assert.True(fsql.DbFirst.ExistsTable("xxxtb.test_existstb01")); + Assert.True(fsql.DbFirst.ExistsTable("xxxtb.Test_existstb01", false)); + fsql.Ado.ExecuteNonQuery("drop table xxxtb.test_existstb01"); + } + class test_existstb01 + { + public Guid id { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/ConvertTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/ConvertTest.cs new file mode 100644 index 00000000..48bfaf92 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/ConvertTest.cs @@ -0,0 +1,169 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class ConvertTest + { + ISelect select => g.sqlserver.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void ToBoolean() + { + var data = new List(); + data.Add(select.Where(a => (Convert.ToBoolean(a.Clicks) ? 1 : 0) > 0).ToList()); + data.Add(select.Where(a => (bool.Parse(a.Clicks.ToString()) ? 1 : 0) > 0).ToList()); + } + [Fact] + public void ToByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToByte(a.Clicks % 255) > 0).ToList()); + data.Add(select.Where(a => byte.Parse((a.Clicks % 255).ToString()) > 0).ToList()); + } + [Fact] + public void ToChar() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToChar(a.Clicks) == '1').ToList()); + data.Add(select.Where(a => char.Parse(a.Clicks.ToString()) == '1').ToList()); + } + [Fact] + public void ToDateTime() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDateTime(a.CreateTime.ToString()).Year > 0).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()).Year > 0).ToList()); + } + [Fact] + public void ToDecimal() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDecimal(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => decimal.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToDouble() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToDouble(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => double.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt16() + { + var data = new List(); + //data.Add(select.Where(a => Convert.ToInt16(a.Clicks) > 0).ToList()); + //data.Add(select.Where(a => short.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt32() + { + var data = new List(); + data.Add(select.Where(a => (int)a.Clicks > 0).ToList()); + data.Add(select.Where(a => Convert.ToInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => int.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => long.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToSByte() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSByte(a.Clicks % 128) > 0).ToList()); + data.Add(select.Where(a => sbyte.Parse((a.Clicks % 128).ToString()) > 0).ToList()); + } + [Fact] + public void ToSingle() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToSingle(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => float.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToString(a.Clicks).Equals("")).ToList()); + data.Add(select.Where(a => a.Clicks.ToString().Equals("")).ToList()); + } + [Fact] + public void ToUInt16() + { + var data = new List(); + //data.Add(select.Where(a => Convert.ToUInt16(a.Clicks) > 0).ToList()); + //data.Add(select.Where(a => ushort.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt32() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt32(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => uint.Parse(a.Clicks.ToString()) > 0).ToList()); + } + [Fact] + public void ToUInt64() + { + var data = new List(); + data.Add(select.Where(a => Convert.ToUInt64(a.Clicks) > 0).ToList()); + data.Add(select.Where(a => ulong.Parse(a.Clicks.ToString()) > 0).ToList()); + } + + [Fact] + public void Guid_Parse() + { + var data = new List(); + data.Add(select.Where(a => Guid.Parse(Guid.NewGuid().ToString()) == Guid.Empty).ToList()); + } + + [Fact] + public void Guid_NewGuid() + { + var data = new List(); + data.Add(select.OrderBy(a => Guid.NewGuid()).Limit(10).ToList()); + } + + [Fact] + public void Random() + { + var data = new List(); + data.Add(select.Where(a => new Random().Next() > a.Clicks).Limit(10).ToList()); + data.Add(select.Where(a => new Random().NextDouble() > a.Clicks).Limit(10).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/DateTimeTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/DateTimeTest.cs new file mode 100644 index 00000000..9dc2dd15 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/DateTimeTest.cs @@ -0,0 +1,349 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class DateTimeTest + { + ISelect select => g.sqlserver.Select(); + + [Table(Name = "tb_topic111333")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + [Table(Name = "TestTypeInfo333")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + public DateTime Time { get; set; } + } + [Table(Name = "TestTypeParentInfo23123")] + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + public DateTime Time2 { get; set; } + } + + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).ToString().Equals(DateTime.Now)).ToList()); + + g.sqlserver.Insert(new Topic()).ExecuteAffrows(); + var dtn = DateTime.Parse("2020-1-1 0:0:0"); + var dts = Enumerable.Range(1, 12).Select(a => dtn.AddMonths(a)) + .Concat(Enumerable.Range(1, 31).Select(a => dtn.AddDays(a))) + .Concat(Enumerable.Range(1, 24).Select(a => dtn.AddHours(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddMinutes(a))) + .Concat(Enumerable.Range(1, 60).Select(a => dtn.AddSeconds(a))); + foreach (var dt in dts) + { + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss.fff"), select.First(a => dt.ToString())); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm:ss"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH:mm"), select.First(a => dt.ToString("yyyy-MM-dd HH:mm"))); + Assert.Equal(dt.ToString("yyyy-MM-dd HH"), select.First(a => dt.ToString("yyyy-MM-dd HH"))); + Assert.Equal(dt.ToString("yyyy-MM-dd"), select.First(a => dt.ToString("yyyy-MM-dd"))); + Assert.Equal(dt.ToString("yyyy-MM"), select.First(a => dt.ToString("yyyy-MM"))); + Assert.Equal(dt.ToString("yyyyMMddHHmmss"), select.First(a => dt.ToString("yyyyMMddHHmmss"))); + Assert.Equal(dt.ToString("yyyyMMddHHmm"), select.First(a => dt.ToString("yyyyMMddHHmm"))); + Assert.Equal(dt.ToString("yyyyMMddHH"), select.First(a => dt.ToString("yyyyMMddHH"))); + Assert.Equal(dt.ToString("yyyyMMdd"), select.First(a => dt.ToString("yyyyMMdd"))); + Assert.Equal(dt.ToString("yyyyMM"), select.First(a => dt.ToString("yyyyMM"))); + Assert.Equal(dt.ToString("yyyy"), select.First(a => dt.ToString("yyyy"))); + Assert.Equal(dt.ToString("HH:mm:ss"), select.First(a => dt.ToString("HH:mm:ss"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h"))); + Assert.Equal(dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t").Replace("", "AM").Replace("", "PM").Replace("", "A").Replace("", "P"), select.First(a => dt.ToString("yyyy MM dd HH mm ss yy M d H hh h m s tt t"))); + } + } + [Fact] + public void Now() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + } + [Fact] + public void UtcNow() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.UtcNow.Date).ToList()); + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MinValue.Date).ToList()); + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.MaxValue.Date).ToList()); + } + [Fact] + public void Date() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Time.Date > DateTime.Now.Date).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Date > DateTime.Now.Date).ToList()); + + data.Add(select.Where(a => DateTime.Now.Subtract(a.CreateTime.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Time.Date).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => DateTime.Now.Subtract(a.Type.Parent.Time2.Date).TotalSeconds > 0).ToList()); + } + [Fact] + public void TimeOfDay() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay == DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Time.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.TimeOfDay > DateTime.Now.TimeOfDay).ToList()); + } + [Fact] + public void DayOfWeek() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfWeek > DateTime.Now.DayOfWeek).ToList()); + } + [Fact] + public void Day() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Time.Day > DateTime.Now.Day).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Day > DateTime.Now.Day).ToList()); + } + [Fact] + public void DayOfYear() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Time.DayOfYear > DateTime.Now.DayOfYear).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.DayOfYear > DateTime.Now.DayOfYear).ToList()); + } + [Fact] + public void Month() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Time.Month > DateTime.Now.Month).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Month > DateTime.Now.Month).ToList()); + } + [Fact] + public void Year() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Time.Year > DateTime.Now.Year).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Year > DateTime.Now.Year).ToList()); + } + [Fact] + public void Hour() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Time.Hour > DateTime.Now.Hour).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Hour > DateTime.Now.Hour).ToList()); + } + [Fact] + public void Minute() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Time.Minute > DateTime.Now.Minute).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Minute > DateTime.Now.Minute).ToList()); + } + [Fact] + public void Second() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Time.Second > DateTime.Now.Second).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Second > DateTime.Now.Second).ToList()); + } + [Fact] + public void Millisecond() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Time.Millisecond > DateTime.Now.Millisecond).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Millisecond > DateTime.Now.Millisecond).ToList()); + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Time.Ticks > DateTime.Now.Ticks).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Ticks > DateTime.Now.Ticks).ToList()); + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Add(TimeSpan.FromDays(1)) > DateTime.Now).ToList()); + } + [Fact] + public void AddDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddDays(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddDays(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddHours(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddHours(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMilliseconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMilliseconds(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMinutes(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMinutes(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddMonths() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddMonths(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddMonths(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddSeconds(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddSeconds(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddTicks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddTicks(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddTicks(1) > DateTime.Now).ToList()); + } + [Fact] + public void AddYears() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1) > DateTime.Now).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1) > DateTime.Now).ToList()); + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(DateTime.Now).TotalSeconds > 0).ToList()); + + data.Add(select.Where(a => a.CreateTime.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Time.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.Subtract(TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + } + [Fact] + public void _ЧͬSubtract() + { + var data = new List(); + data.Add(select.Where(a => (a.CreateTime - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Time - DateTime.Now).TotalSeconds > 0).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - DateTime.Now).TotalSeconds > 0).ToList()); + + data.Add(select.Where(a => (a.CreateTime - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Time - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + data.Add(select.Where(a => (a.Type.Parent.Time2 - TimeSpan.FromDays(1)) > a.CreateTime).ToList()); + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).Equals(DateTime.Now)).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).Equals(DateTime.Now)).ToList()); + } + + [Fact] + public void DateTime_Compare() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Time.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + data.Add(select.Where(a => a.Type.Parent.Time2.AddYears(1).CompareTo(DateTime.Now) == 0).ToList()); + } + [Fact] + public void DateTime_DaysInMonth() + { + var data = new List(); + data.Add(select.Where(a => DateTime.DaysInMonth(a.CreateTime.Year, a.CreateTime.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Time.Year, a.Type.Time.Month) > 30).ToList()); + data.Add(select.Where(a => DateTime.DaysInMonth(a.Type.Parent.Time2.Year, a.Type.Parent.Time2.Month) > 30).ToList()); + } + [Fact] + public void DateTime_Equals() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Equals(a.CreateTime.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Time.AddYears(1), DateTime.Now)).ToList()); + data.Add(select.Where(a => DateTime.Equals(a.Type.Parent.Time2.AddYears(1), DateTime.Now)).ToList()); + } + [Fact] + public void DateTime_IsLeapYear() + { + var data = new List(); + data.Add(select.Where(a => DateTime.IsLeapYear(a.CreateTime.Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Time.AddYears(1).Year)).ToList()); + data.Add(select.Where(a => DateTime.IsLeapYear(a.Type.Parent.Time2.AddYears(1).Year)).ToList()); + } + [Fact] + public void DateTime_Parse() + { + var data = new List(); + data.Add(select.Where(a => DateTime.Parse(a.CreateTime.ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Time.AddYears(1).ToString()) > DateTime.Now).ToList()); + data.Add(select.Where(a => DateTime.Parse(a.Type.Parent.Time2.AddYears(1).ToString()) > DateTime.Now).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/MathTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/MathTest.cs new file mode 100644 index 00000000..8ec22f64 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/MathTest.cs @@ -0,0 +1,156 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class MathTest + { + ISelect select => g.sqlserver.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + + [Fact] + public void PI() + { + var data = new List(); + data.Add(select.Where(a => Math.PI + a.Clicks > 0).ToList()); + } + [Fact] + public void Abs() + { + var data = new List(); + data.Add(select.Where(a => Math.Abs(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Sign() + { + var data = new List(); + data.Add(select.Where(a => Math.Sign(-a.Clicks) > 0).ToList()); + } + [Fact] + public void Floor() + { + var data = new List(); + data.Add(select.Where(a => Math.Floor(a.Clicks + 0.5) == a.Clicks).ToList()); + } + [Fact] + public void Ceiling() + { + var data = new List(); + data.Add(select.Where(a => Math.Ceiling(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Round() + { + var data = new List(); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5) == a.Clicks).ToList()); + data.Add(select.Where(a => Math.Round(a.Clicks + 0.5, 1) > a.Clicks).ToList()); + } + [Fact] + public void Exp() + { + var data = new List(); + data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log() + { + //var data = new List(); + //data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Log10() + { + //var data = new List(); + //data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList()); + } + [Fact] + public void Pow() + { + var data = new List(); + //data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sqrt() + { + var data = new List(); + //data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Cos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Sin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Tan() + { + var data = new List(); + //data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Acos() + { + var data = new List(); + //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Asin() + { + var data = new List(); + //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList()); + } + [Fact] + public void Atan2() + { + var data = new List(); + //data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList()); + } + [Fact] + public void Truncate() + { + var data = new List(); + data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/OtherTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/OtherTest.cs new file mode 100644 index 00000000..7482026a --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/OtherTest.cs @@ -0,0 +1,229 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class OtherTest + { + + ISelect select => g.sqlserver.Select(); + + [Fact] + public void Div() + { + var t1 = select.Where(a => a.testFieldInt / 3 > 3).Limit(10).ToList(); + var t2 = select.Where(a => a.testFieldLong / 3 > 3).Limit(10).ToList(); + var t3 = select.Where(a => a.testFieldShort / 3 > 3).Limit(10).ToList(); + + var t4 = select.Where(a => a.testFieldInt / 3.0 > 3).Limit(10).ToList(); + var t5 = select.Where(a => a.testFieldLong / 3.0 > 3).Limit(10).ToList(); + var t6 = select.Where(a => a.testFieldShort / 3.0 > 3).Limit(10).ToList(); + + var t7 = select.Where(a => a.testFieldDouble / 3 > 3).Limit(10).ToList(); + var t8 = select.Where(a => a.testFieldDecimal / 3 > 3).Limit(10).ToList(); + var t9 = select.Where(a => a.testFieldFloat / 3 > 3).Limit(10).ToList(); + } + + [Fact] + public void Boolean() + { + var t1 = select.Where(a => a.testFieldBool == true).ToList(); + var t2 = select.Where(a => a.testFieldBool != true).ToList(); + var t3 = select.Where(a => a.testFieldBool == false).ToList(); + var t4 = select.Where(a => !a.testFieldBool).ToList(); + var t5 = select.Where(a => a.testFieldBool).ToList(); + var t51 = select.WhereCascade(a => a.testFieldBool).Limit(10).ToList(); + + var t11 = select.Where(a => a.testFieldBoolNullable == true).ToList(); + var t22 = select.Where(a => a.testFieldBoolNullable != true).ToList(); + var t33 = select.Where(a => a.testFieldBoolNullable == false).ToList(); + var t44 = select.Where(a => !a.testFieldBoolNullable.Value).ToList(); + var t55 = select.Where(a => a.testFieldBoolNullable.Value).ToList(); + + var t111 = select.Where(a => a.testFieldBool == true && a.Id > 0).ToList(); + var t222 = select.Where(a => a.testFieldBool != true && a.Id > 0).ToList(); + var t333 = select.Where(a => a.testFieldBool == false && a.Id > 0).ToList(); + var t444 = select.Where(a => !a.testFieldBool && a.Id > 0).ToList(); + var t555 = select.Where(a => a.testFieldBool && a.Id > 0).ToList(); + + var t1111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0).ToList(); + var t2222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0).ToList(); + var t3333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0).ToList(); + var t4444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + var t5555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0).ToList(); + + var t11111 = select.Where(a => a.testFieldBool == true && a.Id > 0 && a.testFieldBool == true).ToList(); + var t22222 = select.Where(a => a.testFieldBool != true && a.Id > 0 && a.testFieldBool != true).ToList(); + var t33333 = select.Where(a => a.testFieldBool == false && a.Id > 0 && a.testFieldBool == false).ToList(); + var t44444 = select.Where(a => !a.testFieldBool && a.Id > 0 && !a.testFieldBool).ToList(); + var t55555 = select.Where(a => a.testFieldBool && a.Id > 0 && a.testFieldBool).ToList(); + + var t111111 = select.Where(a => a.testFieldBoolNullable == true && a.Id > 0 && a.testFieldBoolNullable == true).ToList(); + var t222222 = select.Where(a => a.testFieldBoolNullable != true && a.Id > 0 && a.testFieldBoolNullable != true).ToList(); + var t333333 = select.Where(a => a.testFieldBoolNullable == false && a.Id > 0 && a.testFieldBoolNullable == false).ToList(); + var t444444 = select.Where(a => !a.testFieldBoolNullable.Value && a.Id > 0 && !a.testFieldBoolNullable.Value).ToList(); + var t555555 = select.Where(a => a.testFieldBoolNullable.Value && a.Id > 0 && a.testFieldBoolNullable.Value).ToList(); + } + + [Fact] + public void Array() + { + IEnumerable testlinqlist = new List(new[] { 1, 2, 3 }); + var testlinq = select.Where(a => testlinqlist.Contains(a.testFieldInt)).ToList(); + + //in not in + var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var inarray = new[] { 1, 2, 3 }; + var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + + //in not in + var sql11111 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + var sql11222 = select.Where(a => new List() { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); + var sql11333 = select.Where(a => !new List() { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); + + var sql11111a = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + var sql11222b = select.Where(a => new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt) == false).ToList(); + var sql11333c = select.Where(a => !new List(new[] { 1, 2, 3 }).Contains(a.testFieldInt)).ToList(); + + var inarray2 = new List() { 1, 2, 3 }; + var sql111111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); + var sql112222 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); + var sql113333 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); + + var inarray2n = Enumerable.Range(1, 3333).ToArray(); + var sql1111111 = select.Where(a => inarray2n.Contains(a.testFieldInt)).ToList(); + var sql1122222 = select.Where(a => inarray2n.Contains(a.testFieldInt) == false).ToList(); + var sql1133333 = select.Where(a => !inarray2n.Contains(a.testFieldInt)).ToList(); + + //nvarchar + IEnumerable stringlinqlist = new List(new[] { "a1", "a2", "a3" }); + var ntestlinq = select.Where(a => stringlinqlist.Contains(a.testFieldString)).ToList(); + + //in not in + var nsql111 = select.Where(a => new[] { "a1", "a2", "a3" }.Contains(a.testFieldString)).ToList(); + var nsql112 = select.Where(a => new[] { "a1", "a2", "a3" }.Contains(a.testFieldString) == false).ToList(); + var nsql113 = select.Where(a => !new[] { "a1", "a2", "a3" }.Contains(a.testFieldString)).ToList(); + + var ninarray = new[] { "a1", "a2", "a3" }; + var nsql1111 = select.Where(a => ninarray.Contains(a.testFieldString)).ToList(); + var nsql1122 = select.Where(a => ninarray.Contains(a.testFieldString) == false).ToList(); + var nsql1133 = select.Where(a => !ninarray.Contains(a.testFieldString)).ToList(); + + //in not in + var nsql11111 = select.Where(a => new List() { "a1", "a2", "a3" }.Contains(a.testFieldString)).ToList(); + var nsql11222 = select.Where(a => new List() { "a1", "a2", "a3" }.Contains(a.testFieldString) == false).ToList(); + var nsql11333 = select.Where(a => !new List() { "a1", "a2", "a3" }.Contains(a.testFieldString)).ToList(); + + var nsql11111a = select.Where(a => new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldString)).ToList(); + var nsql11222b = select.Where(a => new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldString) == false).ToList(); + var nsql11333c = select.Where(a => !new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldString)).ToList(); + + var ninarray2 = new List() { "a1", "a2", "a3" }; + var nsql111111 = select.Where(a => ninarray2.Contains(a.testFieldString)).ToList(); + var nsql112222 = select.Where(a => ninarray2.Contains(a.testFieldString) == false).ToList(); + var nsql113333 = select.Where(a => !ninarray2.Contains(a.testFieldString)).ToList(); + + var ninarray2n = Enumerable.Range(1, 3333).Select(a => "testnvarchar" + a).ToArray(); + var nsql1111111 = select.Where(a => ninarray2n.Contains(a.testFieldString)).ToList(); + var nsql1122222 = select.Where(a => ninarray2n.Contains(a.testFieldString) == false).ToList(); + var nsql1133333 = select.Where(a => !ninarray2n.Contains(a.testFieldString)).ToList(); + + //varchar + IEnumerable vstringlinqlist = new List(new[] { "a1", "a2", "a3" }); + var vtestlinq = select.Where(a => vstringlinqlist.Contains(a.testFieldStringVarchar)).ToList(); + + //in not in + var vsql111 = select.Where(a => new[] { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar)).ToList(); + var vsql112 = select.Where(a => new[] { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql113 = select.Where(a => !new[] { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar)).ToList(); + + var vinarray = new[] { "a1", "a2", "a3" }; + var vsql1111 = select.Where(a => ninarray.Contains(a.testFieldStringVarchar)).ToList(); + var vsql1122 = select.Where(a => ninarray.Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql1133 = select.Where(a => !ninarray.Contains(a.testFieldStringVarchar)).ToList(); + + //in not in + var vsql11111 = select.Where(a => new List() { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar)).ToList(); + var vsql11222 = select.Where(a => new List() { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql11333 = select.Where(a => !new List() { "a1", "a2", "a3" }.Contains(a.testFieldStringVarchar)).ToList(); + + var vsql11111a = select.Where(a => new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldStringVarchar)).ToList(); + var vsql11222b = select.Where(a => new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql11333c = select.Where(a => !new List(new[] { "a1", "a2", "a3" }).Contains(a.testFieldStringVarchar)).ToList(); + + var vinarray2 = new List() { "a1", "a2", "a3" }; + var vsql111111 = select.Where(a => ninarray2.Contains(a.testFieldStringVarchar)).ToList(); + var vsql112222 = select.Where(a => ninarray2.Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql113333 = select.Where(a => !ninarray2.Contains(a.testFieldStringVarchar)).ToList(); + + var vinarray2n = Enumerable.Range(1, 3333).Select(a => "testvarchar" + a).ToArray(); + var vsql1111111 = select.Where(a => vinarray2n.Contains(a.testFieldStringVarchar)).ToList(); + var vsql1122222 = select.Where(a => vinarray2n.Contains(a.testFieldStringVarchar) == false).ToList(); + var vsql1133333 = select.Where(a => !vinarray2n.Contains(a.testFieldStringVarchar)).ToList(); + } + + [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; } + + [Column(DbType = "varchar(255)")] + public string testFieldStringVarchar { 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/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/StringTest.cs new file mode 100644 index 00000000..414229bb --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/StringTest.cs @@ -0,0 +1,392 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class StringTest + { + + ISelect select => g.sqlserver.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + class TestEqualsGuid + { + public Guid id { get; set; } + } + + [Fact] + public void Equals__() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Equals("aaa")).ToList()); + list.Add(g.sqlserver.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); + } + + [Fact] + public void StringJoin() + { + var fsql = g.sqlserver; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + } + class StringJoin01 + { + [Column(IsIdentity = true)] + public int id { get; set; } + public string name { get; set; } + } + + [Fact] + public void First() + { + Assert.Equal('x', select.First(a => "x1".First())); + Assert.Equal('z', select.First(a => "z1".First())); + } + [Fact] + public void FirstOrDefault() + { + Assert.Equal('x', select.First(a => "x1".FirstOrDefault())); + Assert.Equal('z', select.First(a => "z1".FirstOrDefault())); + } + + [Fact] + public void Format() + { + var item = g.sqlserver.GetRepository().Insert(new Topic { Clicks = 101, Title = "我是中国人101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.Equal($@"SELECT N'x'+isnull(cast((a.[Id] + 1) as varchar), '')+N'z-'+isnull(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6), '')+N''+isnull(a.[Title], '')+N'' as1, N''+isnull(cast((a.[Id] + 1) as varchar), '')+N'x'+isnull(cast((a.[Id] + 1) as varchar), '')+N'z-'+isnull(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6), '')+N''+isnull(a.[Title], '')+N'' as2 +FROM [tb_topic] a +WHERE (a.[Id] = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title), item2.str2); + } + + [Fact] + public void Format4() + { + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var item = g.sqlserver.GetRepository().Insert(new Topic { Clicks = 101, Title = "我是中国人101", CreateTime = DateTime.Parse("2020-7-5") }); + var sql = select.WhereDynamic(item).ToSql(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.Equal($@"SELECT N'x'+isnull(cast((a.[Id] + 1) as varchar), '')+N'z-'+isnull(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6), '')+N''+isnull(a.[Title], '')+N''+isnull(a.[Title], '')+N'' as1, N''+isnull(cast((a.[Id] + 1) as varchar), '')+N'x'+isnull(cast((a.[Id] + 1) as varchar), '')+N'z-'+isnull(substring(convert(char(8), cast(a.[CreateTime] as datetime), 112), 1, 6), '')+N''+isnull(a.[Title], '')+N''+isnull(a.[Title], '')+N'' as2 +FROM [tb_topic] a +WHERE (a.[Id] = {item.Id})", sql); + + var item2 = select.WhereDynamic(item).First(a => new + { + str = $"x{a.Id + 1}z-{a.CreateTime.ToString("yyyyMM")}{a.Title}{a.Title}", + str2 = string.Format("{0}x{0}z-{1}{2}{3}", a.Id + 1, a.CreateTime.ToString("yyyyMM"), a.Title, a.Title) + }); + Assert.NotNull(item2); + Assert.Equal($"x{item.Id + 1}z-{item.CreateTime.ToString("yyyyMM")}{item.Title}{item.Title}", item2.str); + Assert.Equal(string.Format("{0}x{0}z-{1}{2}{3}", item.Id + 1, item.CreateTime.ToString("yyyyMM"), item.Title, item.Title), item2.str2); + } + + [Fact] + public void Empty() + { + var data = new List(); + data.Add(select.Where(a => (a.Title ?? "") == string.Empty).ToSql()); + } + + [Fact] + public void StartsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.StartsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.StartsWith(a.Type.Name)).ToList()); + + list.Add(select.Where(a => (a.Title + "aaa").StartsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").StartsWith(a.Type.Name)).ToList()); + } + [Fact] + public void EndsWith() + { + var list = new List(); + list.Add(select.Where(a => a.Title.EndsWith("aaa")).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.EndsWith(a.Type.Name)).ToList()); + + list.Add(select.Where(a => (a.Title + "aaa").EndsWith("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").EndsWith(a.Type.Name)).ToList()); + } + [Fact] + public void Contains() + { + var list = new List(); + list.Add(select.Where(a => a.Title.Contains("aaa")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name)).ToList()); + + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1)).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name)).ToList()); + + + list.Add(select.Where(a => a.Title.Contains("%")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + "%")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Title + 1 + "%")).ToList()); + list.Add(select.Where(a => a.Title.Contains(a.Type.Name + "%")).ToList()); + + list.Add(select.Where(a => (a.Title + "aaa").Contains("aaa" + "%")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + "%")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Title + 1 + "%")).ToList()); + list.Add(select.Where(a => (a.Title + "aaa").Contains(a.Type.Name + "%")).ToList()); + } + [Fact] + public void ToLower() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToLower() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToLower() == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToLower() + "aaa").ToLower() == a.Type.Name).ToList()); + } + [Fact] + public void ToUpper() + { + var data = new List(); + data.Add(select.Where(a => a.Title.ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.ToUpper() == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.ToUpper() + "aaa").ToUpper() == a.Type.Name).ToList()); + } + [Fact] + public void Substring() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Substring(0) == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Substring(0) == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(a.Title.Length) == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, a.Title.Length) == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(0, 3) == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Substring(0) + "aaa").Substring(1, 2) == a.Type.Name).ToList()); + } + [Fact] + public void Length() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Length == 0).ToList()); + data.Add(select.Where(a => a.Title.Length == 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => a.Title.Length == a.Type.Name.Length).ToList()); + + data.Add(select.Where(a => (a.Title + "aaa").Length == 0).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Title.Length + 1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").Length == a.Type.Name.Length).ToList()); + } + [Fact] + public void IndexOf() + { + var data = new List(); + data.Add(select.Where(a => a.Title.IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => a.Title.IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa") == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == -1).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == (a.Title.Length + 1)).ToList()); + data.Add(select.Where(a => (a.Title + "aaa").IndexOf("aaa", 2) == a.Type.Name.Length + 1).ToList()); + } + [Fact] + public void PadLeft() + { + //var data = new List(); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == "aaa").ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Title).ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => a.Title.PadLeft(10, 'a') == a.Type.Name).ToList()); + + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == "aaa").ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Title).ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => (a.Title.PadLeft(10, 'a') + "aaa").PadLeft(20, 'b') == a.Type.Name).ToList()); + } + [Fact] + public void PadRight() + { + //var data = new List(); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == "aaa").ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Title).ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => a.Title.PadRight(10, 'a') == a.Type.Name).ToList()); + + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == "aaa").ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Title).ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == (a.Title + 1)).ToList()); + //data.Add(select.Where(a => (a.Title.PadRight(10, 'a') + "aaa").PadRight(20, 'b') == a.Type.Name).ToList()); + } + [Fact] + public void Trim() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Trim() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Trim('a', 'b', 'c') == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.Trim() + "aaa").Trim() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Trim('a') + "aaa").Trim('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b') + "aaa").Trim('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Trim('a', 'b', 'c') + "aaa").Trim('a', 'b', 'c') == a.Type.Name).ToList()); + } + [Fact] + public void TrimStart() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.TrimStart() + "aaa").TrimStart() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a') + "aaa").TrimStart('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b') + "aaa").TrimStart('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimStart('a', 'b', 'c') + "aaa").TrimStart('a', 'b', 'c') == a.Type.Name).ToList()); + } + [Fact] + public void TrimEnd() + { + var data = new List(); + data.Add(select.Where(a => a.Title.TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.TrimEnd() + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a') + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b') + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.TrimEnd('a', 'b', 'c') + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + } + [Fact] + public void Replace() + { + var data = new List(); + data.Add(select.Where(a => a.Title.Replace("a", "b") == "aaa").ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c") == a.Title).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") == (a.Title + 1)).ToList()); + data.Add(select.Where(a => a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") == a.Type.Name).ToList()); + + data.Add(select.Where(a => (a.Title.Replace("a", "b") + "aaa").TrimEnd() == "aaa").ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c") + "aaa").TrimEnd('a') == a.Title).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace("c", "a") + "aaa").TrimEnd('a', 'b') == (a.Title + 1)).ToList()); + data.Add(select.Where(a => (a.Title.Replace("a", "b").Replace("b", "c").Replace(a.Type.Name, "a") + "aaa").TrimEnd('a', 'b', 'c') == a.Type.Name).ToList()); + } + [Fact] + public void CompareTo() + { + //var data = new List(); + //data.Add(select.Where(a => a.Title.CompareTo(a.Title) == 0).ToList()); + //data.Add(select.Where(a => a.Title.CompareTo(a.Title) > 0).ToList()); + //data.Add(select.Where(a => a.Title.CompareTo(a.Title + 1) == 0).ToList()); + //data.Add(select.Where(a => a.Title.CompareTo(a.Title + a.Type.Name) == 0).ToList()); + + //data.Add(select.Where(a => (a.Title + "aaa").CompareTo("aaa") == 0).ToList()); + //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title) > 0).ToList()); + //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Title + 1) == 0).ToList()); + //data.Add(select.Where(a => (a.Title + "aaa").CompareTo(a.Type.Name) == 0).ToList()); + } + + [Fact] + public void string_IsNullOrEmpty() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrEmpty(a.Title)).ToList()); + //data.Add(select.Where(a => string.IsNullOrEmpty(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrEmpty(a.Title)).ToList()); + } + + [Fact] + public void string_IsNullOrWhiteSpace() + { + var data = new List(); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title)).ToList()); + data.Add(select.Where(a => string.IsNullOrWhiteSpace(a.Title) == false).ToList()); + data.Add(select.Where(a => !string.IsNullOrWhiteSpace(a.Title)).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/TimeSpanTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/TimeSpanTest.cs new file mode 100644 index 00000000..4e701de4 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/SqlServer/SqlServerExpression/TimeSpanTest.cs @@ -0,0 +1,210 @@ +using FreeSql.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.Custom.SqlServerExpression +{ + [Collection("SqlServerCollection")] + public class TimeSpanTest + { + + ISelect select => g.sqlserver.Select(); + + [Table(Name = "tb_topic")] + class Topic + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int Clicks { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + class TestTypeInfo + { + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + class TestTypeParentInfo + { + public int Id { get; set; } + public string Name { get; set; } + + public List Types { get; set; } + } + [Fact] + public void Zero() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.Zero).ToList()); + } + [Fact] + public void MinValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay > TimeSpan.MinValue).ToList()); + } + [Fact] + public void MaxValue() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay < TimeSpan.MaxValue).ToList()); + } + [Fact] + public void Days() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Days == 0).ToList()); + } + [Fact] + public void Hours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Hours > 0).ToSql()); + } + [Fact] + public void Milliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Milliseconds > 0).ToList()); + } + [Fact] + public void Minutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Minutes > 0).ToList()); + } + [Fact] + public void Seconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Seconds > 0).ToList()); + } + [Fact] + public void Ticks() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Ticks > 0).ToList()); + } + [Fact] + public void TotalDays() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalDays > 0).ToList()); + } + [Fact] + public void TotalHours() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalHours > 0).ToList()); + } + [Fact] + public void TotalMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMilliseconds > 0).ToList()); + } + [Fact] + public void TotalMinutes() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalMinutes > 0).ToSql()); + } + [Fact] + public void TotalSeconds() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.TotalSeconds > 0).ToList()); + } + [Fact] + public void Add() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Add(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + } + [Fact] + public void Subtract() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Subtract(TimeSpan.FromDays(1)) > TimeSpan.Zero).ToList()); + } + [Fact] + public void CompareTo() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.CompareTo(TimeSpan.FromDays(1)) > 0).ToList()); + } + [Fact] + public void this_Equals() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.Equals(TimeSpan.FromDays(1))).ToList()); + } + [Fact] + public void this_ToString() + { + var data = new List(); + data.Add(select.Where(a => a.CreateTime.TimeOfDay.ToString() == "ssss").ToList()); + } + + [Fact] + public void TimeSpan_Compare() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Compare(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1)) > 0).ToList()); + } + [Fact] + public void TimeSpan_Equals() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + } + [Fact] + public void TimeSpan_FromDays() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromDays(1))).ToList()); + } + [Fact] + public void TimeSpan_FromHours() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromHours(1))).ToList()); + } + [Fact] + public void TimeSpan_FromMilliseconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMilliseconds(1))).ToList()); + } + [Fact] + public void TimeSpan_FromMinutes() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromMinutes(1))).ToList()); + } + [Fact] + public void TimeSpan_FromSeconds() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromSeconds(1))).ToList()); + } + [Fact] + public void TimeSpan_FromTicks() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Equals(a.CreateTime.TimeOfDay, TimeSpan.FromTicks(1))).ToList()); + } + [Fact] + public void TimeSpan_Parse() + { + var data = new List(); + data.Add(select.Where(a => TimeSpan.Parse(a.CreateTime.TimeOfDay.ToString()) > TimeSpan.Zero).ToList()); + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/UnitTest1.cs new file mode 100644 index 00000000..f9dd56db --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/UnitTest1.cs @@ -0,0 +1,1075 @@ +using FreeSql.DataAnnotations; +using FreeSql; +using System; +using System.Collections.Generic; +using Xunit; +using System.Linq; +using Newtonsoft.Json.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; +using System.Collections; +using System.Diagnostics; +using System.ComponentModel.DataAnnotations; +using System.Reflection; + +namespace FreeSql.Tests.Custom +{ + public static class SqlFunc + { + public static T TryTo(this string that) + { + return (T)Internal.Utils.GetDataReaderValue(typeof(T), that); + } + + public static string FormatDateTime() + { + return ""; + } + } + + public class UnitTest1 + { + + public class Order + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string OrderTitle { get; set; } + public string CustomerName { get; set; } + public DateTime TransactionDate { get; set; } + public virtual List OrderDetails { get; set; } + } + public class OrderDetail + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public int OrderId { get; set; } + public virtual Order Order { get; set; } + } + + ISelect select => g.mysql.Select(); + + class TestUser + { + [Column(IsIdentity = true)] + public int stringid { get; set; } + public string accname { get; set; } + public LogUserOn LogOn { get; set; } + + } + class LogUserOn + { + public int id { get; set; } + public int userstrId { get; set; } + } + + class ServiceRequestNew + { + public Guid id { get; set; } + public string acptStaffDeptId { get; set; } + public DateTime acptTime { get; set; } + public int crtWrkfmFlag { get; set; } + [Column(DbType = "nvarchar2(1500)")] + public string srvReqstCntt { get; set; } + } + + public class Model1 + { + [Column(IsIdentity = true)] + public int id { get; set; } + + public string title { get; set; } + + public ICollection Childs { get; set; } + + public int M2Id { get; set; } + + [Column(IsIgnore = true)] + public List TestManys { get; set; } + + } + + public class Model2 + { + + [Column(IsIdentity = true)] + public int id { get; set; } + public string Title { get; set; } + + public Model1 Parent { get; set; } + public int Parent_id { get; set; } + + public string Ccc { get; set; } + public DateTime Date { get; set; } + + [Column(Name = "Waxxx2")] + public int Wa_xxx2 { get; set; } + } + + public class TestEnumable : IEnumerable + { + public IEnumerator GetEnumerator() + { + throw new NotImplementedException(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + throw new NotImplementedException(); + } + } + + public class TestEnum + { + public Guid id { get; set; } + public Enum em { get; set; } + } + + /// + /// + /// + [Table(Name = "news_article")] + public class NewsArticle + { + /// + /// + /// + [Column(Name = "article_id", IsIdentity = true, IsPrimary = true)] + public int ArticleId { get; set; } + + /// + /// + /// + [Column(Name = "article_title")] + public string ArticleTitle { get; set; } + + /// + /// + /// + [Column(Name = "category_id")] + public int CategoryId { get; set; } + + /// + /// + /// + [Column(Name = "channel_id")] + public int ChannelId { get; set; } + + /// + /// 类型 + /// + [Column(Name = "type_id")] + public int TypeId { get; set; } + + /// + /// 内容简介 + /// + [Column(Name = "summary")] + public string Summary { get; set; } + + /// + /// 缩略图 + /// + [Column(Name = "thumbnail")] + public string Thumbnail { get; set; } + + /// + /// 点击量 + /// + [Column(Name = "hits")] + public int Hits { get; set; } + + /// + /// + /// + [Column(Name = "is_display")] + public int IsDisplay { get; set; } + + /// + /// + /// + [Column(Name = "status")] + public int Status { get; set; } + + /// + /// + /// + [Column(Name = "create_time")] + public int CreateTime { get; set; } + + /// + /// + /// + [Column(Name = "release_time")] + public int ReleaseTime { get; set; } + + public DateTime testaddtime { get; set; } + public DateTime? testaddtime2 { get; set; } + } + + public class NewsArticleDto : NewsArticle + { + + } + + + public class TaskBuildInfo + { + [FreeSql.DataAnnotations.Column(IsPrimary = true)] + public Guid Id { get; set; } + public Guid TbId { get; set; } + public Guid DataBaseConfigId { get; set; } + public string Name { get; set; } + public int Level { get; set; } + + [Column(IsIgnore = true)] + public virtual TaskBuild TaskBuild { get; set; } + } + public class Templates + { + /// + /// 测试中文重命名id + /// + [Column(IsPrimary = true, OldName = "Id")] + public Guid Id2 { get; set; } + public string Title { get; set; } + public DateTime AddTime { get; set; } = DateTime.Now; + public DateTime EditTime { get; set; } + public string Code { get; set; } + } + public class TaskBuild + { + + [FreeSql.DataAnnotations.Column(IsPrimary = true)] + public Guid Id { get; set; } + public string TaskName { get; set; } + public Guid TemplatesId { get; set; } + public string GeneratePath { get; set; } + public string FileName { get; set; } + public string NamespaceName { get; set; } + public bool OptionsEntity01 { get; set; } = false; + public bool OptionsEntity02 { get; set; } = false; + public bool OptionsEntity03 { get; set; } = false; + public int OptionsEntity04 { get; set; } + public int? score { get; set; } + + [Navigate("TbId")] + public virtual ICollection Builds { get; set; } + public Templates Templates { get; set; } + + public Guid ParentId { get; set; } + public TaskBuild Parent { get; set; } + } + + + + void parseExp(object sender, Aop.ParseExpressionEventArgs e) + { + if (e.Expression.NodeType == ExpressionType.Call) + { + var callExp = e.Expression as MethodCallExpression; + if (callExp.Object == null && callExp.Arguments.Any() && callExp.Arguments[0].Type == typeof(string)) + { + if (callExp.Method.Name == "TryTo") + { + e.Result = Expression.Lambda( + typeof(Func<>).MakeGenericType(callExp.Method.GetGenericArguments().FirstOrDefault()), + e.Expression).Compile().DynamicInvoke()?.ToString(); + return; + } + } + } + } + + public class Class1 + { + [Column(IsIdentity = true)] + public long ID { set; get; } + + [Column(IsIdentity = true, OldName = "stu_id_log")] + public long stu_id { set; get; } + /// + /// 姓名 + /// + public string name { set; get; } + + public int age { set; get; } + + public DateTime class2 { set; get; } + } + + class TestDto + { + public Guid Id { get; set; } + public bool IsLeaf { get; set; } + } + + public static int GetUNIX_TIMESTAMP() => 0; + + + [Table(Name = "bz_web_post")] + public class Post + { + public int Id { get; set; } + public int AuthorId { get; set; } + [Navigate("AuthorId")] + public AuthorTest Author { get; set; } + } + [Table(Name = "bz_web_authortest")] + public class AuthorTest + { + public int Id { get; set; } + public string Name { get; set; } + [Navigate("AuthorId")] + public List Post { get; set; } + } + + [Fact] + public void Test1() + { + + using (var conn = g.oracle.Ado.MasterPool.Get()) { + var cmd = conn.Value.CreateCommand(); + cmd.CommandText = @"SELECT a.""ID"" as1, a__Type.""NAME"" as2 +FROM ""TB_TOPIC22"" a +LEFT JOIN ""TESTTYPEINFO"" a__Type ON a__Type.""GUID"" = a.""TYPEGUID"" +WHERE ROWNUM < 11"; + var dr = cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection); + + var eof = dr.Read(); + + dr.Close(); + } + + + var ttt = g.oracle.Select().ToList(); + + + var testrunsql1 = g.mysql.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); + var testrunsql3 = g.sqlserver.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); + var testrunsql4 = g.oracle.Select().Where(a => a.OptionsEntity04 > DateTime.Now.AddDays(0).ToString("yyyyMMdd").TryTo()).ToSql(); + + var testformatsql1 = g.mysql.Select().Where(a => a.NamespaceName == $"1_{10100}").ToSql(); + var testorderbysql = g.mysql.Select().OrderByDescending(a => a.OptionsEntity04 + (a.score ?? 0)).ToSql(); + + var floorSql1 = g.mysql.Select().Where(a => a.OptionsEntity04 / 10000 == 121212 / 10000).ToSql(); + var floorSql2 = g.mysql.Select().Where(a => a.OptionsEntity04 / 10000.0 == 121212 / 10000).ToSql(); + + var testBoolSql1 = g.sqlserver.Select().Where(a => a.OptionsEntity01).ToSql(); + var testBoolSql2 = g.sqlserver.Select().Where(a => a.Id == Guid.NewGuid() && a.OptionsEntity01).ToSql(); + + //g.mysql.Aop.AuditValue += (s, e) => + //{ + // if (e.Column.CsType == typeof(long) + // && e.Property.GetCustomAttribute(false) != null + // && e.Value?.ToString() == "0") + // e.Value = new Random().Next(); + //}; + //g.mysql.GetRepository().Insert(GetSystemUser()); + + g.mysql.Aop.ParseExpression += new EventHandler((s, e) => + { + if (e.Expression.NodeType == ExpressionType.Call && (e.Expression as MethodCallExpression).Method.Name == "GetUNIX_TIMESTAMP") + e.Result = "UNIX_TIMESTAMP(NOW())"; + }); + var dkkdksdjgj = g.mysql.Select().Where(a => a.OptionsEntity04 > GetUNIX_TIMESTAMP()).ToSql(); + + var dt1970 = new DateTime(1970, 1, 1); + var dkkdksdjgj22 = g.mysql.Select().Where(a => a.OptionsEntity04 > DateTime.Now.Subtract(dt1970).TotalSeconds).ToSql(); + + + var xxxhzytuple = g.sqlserver.Select() + .Where(a => a.t1.Code == "xxx" && a.t2.OptionsEntity03 == true) + .ToSql(); + + + var xxxkdkd = g.oracle.Select() + .InnerJoin((a,b) => true) + .Where((a,b) => (DateTime.Now - a.EditTime).TotalMinutes > 100) + .OrderBy((a,b) => g.oracle.Select().Where(c => b.Id == c.Id2).Count()) + .ToSql(); + + + g.oracle.Aop.SyncStructureAfter += (s, e) => + Trace.WriteLine(e.Sql); + + g.oracle.CodeFirst.SyncStructure(); + + //g.mysql.Aop.ParseExpression += parseExp; + + //var sqdddd2 = g.mysql.Select().ToSql(t => t.OptionsEntity04 == t.NamespaceName.TryTo()); + + var sqksdkfjl = g.mysql.Select() + .LeftJoin(a => a.Templates.Id2 == a.TemplatesId) + .LeftJoin(a => a.Parent.Id == a.Id) + .LeftJoin(a => a.Parent.Templates.Id2 == a.Parent.TemplatesId) + .ToSql(a => new + { + code1 = a.Templates.Code, + code2 = a.Parent.Templates.Code + }); + + + var sqksdkfjl2223 = g.mysql.Select().From((s1, tb2, b1, b2) => s1 + .LeftJoin(a => a.Id == tb2.TemplatesId) + .LeftJoin(a => a.TemplatesId == b1.Id2) + .LeftJoin(a => a.TemplatesId == b2.Id2) + ).ToSql((a, tb2, b1, b2) => new + { + code1 = b1.Code, + code2 = b2.Code + }); + + var tkdkdksql = g.mysql.Select().From((a, b, c) => + a.LeftJoin(aa => aa.TemplatesId == b.Id2 && b.Code == "xx") + .LeftJoin(aa => aa.TemplatesId == c.Id2)) + .GroupBy((a, b, c) => new { a.NamespaceName, c.Code }) + .ToSql("a.id"); + + + + var dcksdkdsk = g.mysql.Select().Where(a => a.testaddtime2.HasValue).ToSql(); + var dcksdkdsk2 = g.mysql.Select().Where(a => !a.testaddtime2.HasValue).ToSql(); + + var testgrpsql = g.mysql.Select() + .From((a, b) => a.InnerJoin(aa => aa.TemplatesId + == b.Id2)) + .GroupBy((a, b) => b.Code) + .ToSql(a => new + { + a.Key, + sss = a.Sum(a.Value.Item1.OptionsEntity04) + }); + + var testgrpsql2 = g.mysql.Select() + .From((a, b) => a.InnerJoin(aa => aa.TemplatesId + == b.Id2)) + .GroupBy((a, b) => b.Code) + .ToList(a => new + { + a.Key, + sss = a.Sum(a.Value.Item1.OptionsEntity04) + }); + + + var tbid = g.mysql.Select().First()?.Id ?? Guid.Empty; + + var testarray = new[] { 1, 2, 3 }; + var tbidsql1 = g.mysql.Update().Where(a => a.Id == tbid) + .Set(a => new TaskBuild + { + FileName = "111", + TaskName = a.TaskName + "333", + OptionsEntity02 = false, + OptionsEntity04 = testarray[0] + }).ToSql(); + var tbidsql2 = g.mysql.Update().Where(a => a.Id == tbid) + .Set(a => new + { + FileName = "111", + TaskName = a.TaskName + "333", + OptionsEntity02 = false, + OptionsEntity04 = testarray[0] + }).ToSql(); + + + var dkdkdkd = g.oracle.Select().ToList(); + + + + //var testaddlist = new List(); + //for(var a = 0; a < 133905; a++) { + // testaddlist.Add(new NewsArticle { + // ArticleTitle = "testaddlist_topic" + a, + // Hits = a, + // }); + //} + //g.mysql.Insert(testaddlist) + // //.NoneParameter() + // .ExecuteAffrows(); + + + g.mysql.Aop.ParseExpression += (s, e) => + { + if (e.Expression.NodeType == ExpressionType.Call) + { + var callExp = e.Expression as MethodCallExpression; + if (callExp.Object?.Type == typeof(DateTime) && + callExp.Method.Name == "ToString" && + callExp.Arguments.Count == 1 && + callExp.Arguments[0].Type == typeof(string) && + callExp.Arguments[0].NodeType == ExpressionType.Constant) + { + var format = (callExp.Arguments[0] as ConstantExpression)?.Value?.ToString(); + + if (string.IsNullOrEmpty(format) == false) + { + var tmp = e.FreeParse(callExp.Object); + + switch (format) + { + case "yyyy-MM-dd HH:mm": + tmp = $"date_format({tmp}, '%Y-%m-%d %H:%i')"; + break; + } + e.Result = tmp; + } + } + } + }; + + g.mysql.Select().ToList(a => new + { + testaddtime = a.testaddtime.ToString("yyyy-MM-dd HH:mm") + }); + + var ttdkdk = g.mysql.Select().Where(a => a.NamespaceName == "ddd").ToSql(); + + var tsqlddd = g.mysql.Select().Where(a => + g.mysql.Select().Where(b => b.NamespaceName == a.ArticleTitle) + .Where("@id=1", new { id = 1 }).Any() + ).ToSql(); + + + g.mysql.SetDbContextOptions(opt => opt.EnableCascadeSave = true); + var trepo = g.mysql.GetGuidRepository(); + trepo.Insert(new TaskBuild + { + TaskName = "tt11", + Builds = new[] { + new TaskBuildInfo { + Level = 1, + Name = "t111_11" + } + } + }); + + var ttdkdkd = trepo.Select.Where(a => a.Builds.AsSelect().Any()).ToList(); + + var list1113233 = trepo.Select.ToList(); + + + var entity = new NewsArticle + { + ArticleId = 1, + ArticleTitle = "测试标题" + }; + var where = new NewsArticle + { + ArticleId = 1, + ChannelId = 1, + }; + + g.mysql.Insert(new[] { entity }).ExecuteAffrows(); + + var sqldddkdk = g.mysql.Update(where) + .SetSource(entity) + .UpdateColumns(x => new { x.Status, x.CategoryId, x.ArticleTitle }) + .ToSql(); + + + var sql1111333 = g.mysql.Update() + .SetSource(new Model2 { id = 1, Title = "xxx", Parent_id = 0 }) + .UpdateColumns(x => new { x.Parent_id, x.Date, x.Wa_xxx2 }) + .NoneParameter() + .ToSql(); + + + g.mysql.Insert(new TestEnum { }).ExecuteAffrows(); + var telist = g.mysql.Select().ToList(); + + Assert.Throws(() => g.mysql.CodeFirst.SyncStructure()); + + var TestEnumable = new TestEnumable(); + + + g.mysql.GetRepository().Insert(new Model1 + { + title = "test_" + DateTime.Now.ToString("yyyyMMddHHmmss"), + M2Id = DateTime.Now.Second + DateTime.Now.Minute, + Childs = new[] { + new Model2 { + Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0001", + }, + new Model2 { + Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0002", + }, + new Model2 { + Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0003", + }, + new Model2 { + Title = "model2Test_title_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "0004", + } + } + }); + + var includet1 = g.mysql.Select() + .IncludeMany(a => a.Childs.Take(2), s => s.Where(a => a.id > 0)) + .IncludeMany(a => a.TestManys.Take(1).Where(b => b.id == a.id)) + .Where(a => a.id > 10) + .ToList(); + + var ttt1 = g.mysql.Select().Where(a => a.Childs.AsSelect().Any(b => b.Title == "111")).ToList(); + var testpid1 = g.mysql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); + g.mysql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); + + var aggsql1 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist1 = select + .GroupBy(a => a.Title) + .ToList(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToSql(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + var aggtolist2 = select + .GroupBy(a => new { a.Title, yyyy = string.Concat(a.CreateTime.Year, '-', a.CreateTime.Month) }) + .ToList(b => new + { + b.Key.Title, + b.Key.yyyy, + + cou = b.Count(), + sum = b.Sum(b.Key.yyyy), + sum2 = b.Sum(b.Value.TypeGuid) + }); + + var aggsql3 = select + .GroupBy(a => a.Title) + .ToSql(b => new + { + b.Key, + cou = b.Count(), + sum = b.Sum(b.Key), + sum2 = b.Sum(b.Value.TypeGuid), + sum3 = b.Sum(b.Value.Type.Parent.Parent.Id) + }); + + var sqlrepos = g.mysql.GetRepository(); + sqlrepos.Insert(new TestTypeParentInfo + { + Name = "testroot", + Childs = new[] { + new TestTypeParentInfo { + Name = "testpath2", + Childs = new[] { + new TestTypeParentInfo { + Name = "testpath3", + Childs = new[] { + new TestTypeParentInfo { + Name = "11" + } + } + } + } + } + } + }); + + var sql = g.mysql.Select().Where(a => a.Parent.Parent.Parent.Name == "testroot").ToSql(); + var sql222 = g.mysql.Select().Where(a => a.Parent.Parent.Parent.Name == "testroot").ToList(); + + + Expression> orderBy = null; + orderBy = a => a.CreateTime; + var testsql1 = select.OrderBy(orderBy).ToSql(); + + orderBy = a => a.Title; + + var testsql2 = select.OrderBy(orderBy).ToSql(); + + + var testjson = @"[ +{ +""acptNumBelgCityName"":""泰州"", +""concPrsnName"":""常**"", +""srvReqstTypeName"":""家庭业务→网络质量→家庭宽带→自有宽带→功能使用→游戏过程中频繁掉线→全局流转"", +""srvReqstCntt"":""客户来电表示宽带使用( 所有)出现(频繁掉线不稳定) ,客户所在地址为(安装地址泰州地区靖江靖城街道工农路科技小区科技3区176号2栋2单元502),联系方式(具体联系方式),烦请协调处理。"", +""acptTime"":""2019-04-15 15:17:05"", +""acptStaffDeptId"":""0003002101010001000600020023"" +}, +{ +""acptNumBelgCityName"":""苏州"", +""concPrsnName"":""龚**"", +""srvReqstTypeName"":""移动业务→基础服务→账/详单→全局流转→功能使用→账/详单信息不准确→全局流转"", +""srvReqstCntt"":""用户参与 2018年苏州任我用关怀活动 送的分钟数500分钟,说自己只使用了116分钟,但是我处查询到本月已经使用了306分钟\r\n,烦请处理"", +""acptTime"":""2019-04-15 15:12:05"", +""acptStaffDeptId"":""0003002101010001000600020023"" +} +]"; + //var dic = Newtonsoft.Json.JsonConvert.DeserializeObject>(testjson); + var reqs = Newtonsoft.Json.JsonConvert.DeserializeObject>(testjson); + reqs.ForEach(t => + { + g.oracle.Insert(t).ExecuteAffrows(); + + }); + + + + var sql111 = g.mysql.Select().AsTable((a, b) => "(select * from TestUser where stringid > 10)").Page(1, 10).ToSql(); + + + var xxx = g.mysql.Select().GroupBy(a => new { a.stringid }).ToList(a => a.Key.stringid); + + var tuser = g.mysql.Select().Where(u => u.accname == "admin") + .InnerJoin(a => a.LogOn.id == a.stringid).ToSql(); + + + var parentSelect1 = select.Where(a => a.Type.Parent.Parent.Parent.Parent.Name == "").Where(b => b.Type.Name == "").ToSql(); + + + var collSelect1 = g.mysql.Select().Where(a => + a.OrderDetails.AsSelect().Any(b => b.Id > 100) + ); + + var collectionSelect = select.Where(a => + //a.Type.Guid == a.TypeGuid && + //a.Type.Parent.Id == a.Type.ParentId && + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any( + //b => b.ParentId == a.Type.Parent.Id + ) + ); + + var collectionSelect2 = select.Where(a => + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any( + b => b.Parent.Name == "xxx" && b.Parent.Parent.Name == "ccc" + && b.Parent.Parent.Parent.Types.AsSelect().Any(cb => cb.Name == "yyy") + ) + ); + + var collectionSelect3 = select.Where(a => + a.Type.Parent.Types.AsSelect().Where(b => b.Name == a.Title).Any( + bbb => bbb.Parent.Types.AsSelect().Where(lv2 => lv2.Name == bbb.Name + "111").Any( + ) + ) + ); + + + var neworder = new Order + { + CustomerName = "testCustomer", + OrderTitle = "xxx#cccksksk", + TransactionDate = DateTime.Now, + OrderDetails = new List(new[] { + new OrderDetail { + + }, + new OrderDetail { + + } + }) + }; + + g.mysql.GetRepository().Insert(neworder); + + var order = g.mysql.Select().Where(a => a.Id == neworder.Id).ToOne(); //查询订单表 + if (order == null) + { + var orderId = g.mysql.Insert(new Order { }).ExecuteIdentity(); + order = g.mysql.Select(orderId).ToOne(); + } + + + var orderDetail1 = order.OrderDetails; //第一次访问,查询数据库 + var orderDetail2 = order.OrderDetails; //第二次访问,不查 + var order1 = orderDetail1.FirstOrDefault().Order; //访问导航属性,此时不查数据库,因为 OrderDetails 查询出来的时候已填充了该属性 + + + var queryable = g.mysql.Queryable().Where(a => a.Id == 1).ToList(); + + var sql2222 = select.Where(a => + select.Where(b => b.Id == a.Id && + select.Where(c => c.Id == b.Id).Where(d => d.Id == a.Id).Where(e => e.Id == b.Id) + //.Offset(a.Id) + .Any() + ).Any() + ).ToList(); + + + var groupbysql = g.mysql.Select().From((s, b, c) => s + .Where(a => a.Id == 1) + .WhereIf(false, a => a.Id == 2) + ) + .WhereIf(true, (a, b, c) => a.Id == 3) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()).ToSql(a => new + { + cou = a.Sum(a.Value.Item1.Id), + a.Key.mod4, + a.Key.tt2, + max = a.Max("a.id"), + max2 = Convert.ToInt64("max(a.id)") + }); + + var groupbysql2 = g.mysql.Select().From((s, b, c) => s + .Where(a => a.Id == 1) + .WhereIf(true, a => a.Id == 2) + ) + .WhereIf(false, (a, b, c) => a.Id == 3) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()).ToSql(a => a.Key.mod4); + + var groupby = g.mysql.Select().From((s, b, c) => s + .Where(a => a.Id == 1) + .WhereIf(true, a => a.Id == 2) + ) + .WhereIf(true, (a, b, c) => a.Id == 3) + .GroupBy((a, b, c) => new { tt2 = a.Title.Substring(0, 2), mod4 = a.Id % 4 }) + .Having(a => a.Count() > 0 && a.Avg(a.Key.mod4) > 0 && a.Max(a.Key.mod4) > 0) + .Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100) + .OrderBy(a => a.Key.tt2) + .OrderByDescending(a => a.Count()) + .ToList(a => new + { + a.Key.tt2, + cou1 = a.Count(), + empty = "", + nil = (string)null, + arg1 = a.Avg(a.Key.mod4), + ccc2 = a.Key.tt2 ?? "now()", + //ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)") + }); + + var arrg = g.mysql.Select().ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + + var arrg222 = g.mysql.Select().ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) }); + + var t1 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + var t2 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + + + var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToList(); + var sql2 = select.LeftJoin((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToList(); + var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToList(); + + //g.mysql.Select().Join((a, b, c) => new Model.JoinResult3( + // Model.JoinType.LeftJoin, a.TypeGuid == b.Guid, + // Model.JoinType.InnerJoin, c.Id == b.ParentId && c.Name == "xxx") + //); + + //var sql4 = select.From((a, b, c) => new SelectFrom() + // .InnerJoin(a.TypeGuid == b.Guid) + // .LeftJoin(c.Id == b.ParentId) + // .Where(b.Name == "xxx")) + //.Where(a => a.Id == 1).ToSql(); + + var sql4 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name == "xxx")).ToList(); + //.Where(a => a.Id == 1).ToSql(); + + + var list111 = select.From((s, b, c) => s + .InnerJoin(a => a.TypeGuid == b.Guid) + .LeftJoin(a => c.Id == b.ParentId) + .Where(a => b.Name != "xxx")) + .ToList((a, b, c) => new + { + a.Id, + a.Title, + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + }); + + var ttt122 = g.mysql.Select().Where(a => a.Id > 0).ToList(); + + + + + var sql5 = g.mysql.Select().From((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToList(); + + + + + + //((JoinType.LeftJoin, a.TypeGuid == b.Guid), (JoinType.InnerJoin, b.ParentId == c.Id) + + var t11112 = g.mysql.Select().ToList(a => new + { + a.Id, + a.Title, + a.Type, + ccc = new { a.Id, a.Title }, + tp = a.Type, + tp2 = new + { + a.Id, + tp2 = a.Type.Name + }, + tp3 = new + { + a.Id, + tp33 = new + { + a.Id + } + } + + }); + + var t100 = g.mysql.Select().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + var t101 = g.mysql.Select().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList(); + + + var t1111 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type }); + + var t2222 = g.mysql.Select().ToList(a => new { a.Id, a.Title, a.Type.Name }); + + var t3 = g.mysql.Insert(new[] { new TestInfo { }, new TestInfo { } }).IgnoreColumns(a => a.Title).ToSql(); + var t4 = g.mysql.Insert(new[] { new TestInfo { }, new TestInfo { } }).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); + var t5 = g.mysql.Insert(new[] { new TestInfo { }, new TestInfo { } }).IgnoreColumns(a => new { a.Title, a.TypeGuid, a.CreateTime }).ToSql(); + var t6 = g.mysql.Insert(new[] { new TestInfo { }, new TestInfo { } }).InsertColumns(a => new { a.Title }).ToSql(); + + var t7 = g.mysql.Update().ToSql(); + var t8 = g.mysql.Update().Where(new TestInfo { }).ToSql(); + var t9 = g.mysql.Update().Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).ToSql(); + var t10 = g.mysql.Update().Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).Where(a => a.Title == "111").ToSql(); + var t11 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).ToSql(); + var t12 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Where(a => a.Title == "111").ToSql(); + + var t13 = g.mysql.Update().Set(a => a.Title, "222111").ToSql(); + var t14 = g.mysql.Update().Set(a => a.Title, "222111").Where(new TestInfo { }).ToSql(); + var t15 = g.mysql.Update().Set(a => a.Title, "222111").Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).ToSql(); + var t16 = g.mysql.Update().Set(a => a.Title, "222111").Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).Where(a => a.Title == "111").ToSql(); + var t17 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Set(a => a.Title, "222111").ToSql(); + var t18 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Set(a => a.Title, "222111").Where(a => a.Title == "111").ToSql(); + + var t19 = g.mysql.Update().Set(a => a.TypeGuid + 222111).ToSql(); + var t20 = g.mysql.Update().Set(a => a.TypeGuid + 222111).Where(new TestInfo { }).ToSql(); + var t21 = g.mysql.Update().Set(a => a.TypeGuid + 222111).Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).ToSql(); + var t22 = g.mysql.Update().Set(a => a.TypeGuid + 222111).Where(new[] { new TestInfo { Id = 1 }, new TestInfo { Id = 2 } }).Where(a => a.Title == "111").ToSql(); + var t23 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Set(a => a.TypeGuid + 222111).ToSql(); + var t24 = g.mysql.Update().SetSource(new[] { new TestInfo { Id = 1, Title = "111" }, new TestInfo { Id = 2, Title = "222" } }).Set(a => a.TypeGuid + 222111).Where(a => a.Title == "111").ToSql(); + + + var t1000 = g.mysql.Select().ToSql(); + var t1001 = g.mysql.Insert().AppendData(new ExamPaper()).ToSql(); + } + } + class NullAggreTestTable + { + [Column(IsIdentity = true)] + public int Id { get; set; } + } + + + [Table(Name = "TestInfoT1")] + class TestInfo + { + [Column(IsIdentity = true, IsPrimary = true)] + public int Id { get; set; } + public int TypeGuid { get; set; } + public TestTypeInfo Type { get; set; } + public string Title { get; set; } + public DateTime CreateTime { get; set; } + } + + [Table(Name = "TestTypeInfoT1")] + class TestTypeInfo + { + [Column(IsIdentity = true)] + public int Guid { get; set; } + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public string Name { get; set; } + } + + [Table(Name = "TestTypeParentInfoT1")] + class TestTypeParentInfo + { + [Column(IsIdentity = true)] + public int Id { get; set; } + public string Name { get; set; } + + public int ParentId { get; set; } + public TestTypeParentInfo Parent { get; set; } + public ICollection Childs { get; set; } + + public List Types { get; set; } + } + + + /// + /// 试卷表 + /// + [Table(Name = "exam_paper")] + public class ExamPaper + { + + public long id { get; set; } + + /// + /// 考核计划ID + /// + public long AssessmentPlanId { get; set; } + /// + /// 总分 + /// + public int TotalScore { get; set; } + + public DateTime BeginTime { get; set; } + + public DateTime? EndTime { get; set; } + + //[Column(IsIgnore = true)] + //public ExamStatus Status { get; set; } + public ExamStatus Status + { + get + { + if (DateTime.Now <= BeginTime) + return ExamStatus.Wait; + if (BeginTime <= DateTime.Now && (!EndTime.HasValue || DateTime.Now < EndTime)) + return ExamStatus.Started; + if (BeginTime <= DateTime.Now && (EndTime.HasValue && EndTime <= DateTime.Now)) + return ExamStatus.End; + return ExamStatus.Wait; + } + } + } + public enum ExamStatus { Wait, Started, End } +} diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Custom/g.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/g.cs new file mode 100644 index 00000000..51bd9b31 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Custom/g.cs @@ -0,0 +1,77 @@ +using MySqlConnector; +using Npgsql; +using Oracle.ManagedDataAccess.Client; +using System; +using System.Collections.Generic; +using System.Data.SqlClient; +using System.Diagnostics; +using System.Text; + + +public class g +{ + static Lazy mysqlLazy = new Lazy(() => + { + var fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionFactory(FreeSql.DataType.CustomMySql, () => new MySqlConnection("Server=127.0.0.1;Persist Security Info=False;UID=root;PWD=root;DATABASE=cccddd_custom;Charset=utf8;SslMode=none;")) + .UseAutoSyncStructure(true) + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .UseLazyLoading(true) + .Build(); + fsql.SetDbProviderFactory(MySqlConnectorFactory.Instance); + return fsql; + }); + public static IFreeSql mysql => mysqlLazy.Value; + + static Lazy sqlserverLazy = new Lazy(() => + { + var fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionFactory(FreeSql.DataType.CustomSqlServer, () => new SqlConnection("Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_custom;Pooling=true;")) + .UseAutoSyncStructure(true) + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .UseLazyLoading(true) + .Build(); + fsql.SetDbProviderFactory(SqlClientFactory.Instance); + return fsql; + }); + public static IFreeSql sqlserver => sqlserverLazy.Value; + + static Lazy oracleLazy = new Lazy(() => + { + var fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionFactory(FreeSql.DataType.CustomOracle, () => new OracleConnection("user id=1custom;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2")) + .UseAutoSyncStructure(true) + .UseLazyLoading(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + //.UseNoneCommandParameter(true) + + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .Build(); + fsql.SetDbProviderFactory(OracleClientFactory.Instance); + return fsql; + }); + public static IFreeSql oracle => oracleLazy.Value; + + static Lazy pgsqlLazy = new Lazy(() => + { + var fsql = new FreeSql.FreeSqlBuilder() + .UseConnectionFactory(FreeSql.DataType.CustomPostgreSQL, () => new NpgsqlConnection("Server=192.168.164.10;Port=5432;UID=postgres;PWD=123456;Database=tedb_custom;Pooling=true;")) + .UseAutoSyncStructure(true) + .UseNameConvert(FreeSql.Internal.NameConvertType.ToLower) + .UseLazyLoading(true) + .UseMonitorCommand( + cmd => Trace.WriteLine(cmd.CommandText), //监听SQL命令对象,在执行前 + (cmd, traceLog) => Console.WriteLine(traceLog)) + .Build(); + fsql.SetDbProviderFactory(NpgsqlFactory.Instance); + return fsql; + }); + public static IFreeSql pgsql => pgsqlLazy.Value; + +} diff --git a/FreeSql.sln b/FreeSql.sln index a5c7d6db..1c2d9ddb 100644 --- a/FreeSql.sln +++ b/FreeSql.sln @@ -115,6 +115,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.OracleOled EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.OracleOledb", "FreeSql.Tests\FreeSql.Tests.Provider.OracleOledb\FreeSql.Tests.Provider.OracleOledb.csproj", "{1DA3FF04-AA2C-4374-9368-68931D8D5B09}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Tests.Provider.Custom", "FreeSql.Tests\FreeSql.Tests.Provider.Custom\FreeSql.Tests.Provider.Custom.csproj", "{530E3032-F7CE-4EB2-9F21-B7D46331B9E6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -677,6 +679,18 @@ Global {1DA3FF04-AA2C-4374-9368-68931D8D5B09}.Release|x64.Build.0 = Release|Any CPU {1DA3FF04-AA2C-4374-9368-68931D8D5B09}.Release|x86.ActiveCfg = Release|Any CPU {1DA3FF04-AA2C-4374-9368-68931D8D5B09}.Release|x86.Build.0 = Release|Any CPU + {530E3032-F7CE-4EB2-9F21-B7D46331B9E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {530E3032-F7CE-4EB2-9F21-B7D46331B9E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {530E3032-F7CE-4EB2-9F21-B7D46331B9E6}.Debug|x64.ActiveCfg = Debug|Any CPU + {530E3032-F7CE-4EB2-9F21-B7D46331B9E6}.Debug|x64.Build.0 = Debug|Any CPU + {530E3032-F7CE-4EB2-9F21-B7D46331B9E6}.Debug|x86.ActiveCfg = Debug|Any CPU + {530E3032-F7CE-4EB2-9F21-B7D46331B9E6}.Debug|x86.Build.0 = Debug|Any CPU + {530E3032-F7CE-4EB2-9F21-B7D46331B9E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {530E3032-F7CE-4EB2-9F21-B7D46331B9E6}.Release|Any CPU.Build.0 = Release|Any CPU + {530E3032-F7CE-4EB2-9F21-B7D46331B9E6}.Release|x64.ActiveCfg = Release|Any CPU + {530E3032-F7CE-4EB2-9F21-B7D46331B9E6}.Release|x64.Build.0 = Release|Any CPU + {530E3032-F7CE-4EB2-9F21-B7D46331B9E6}.Release|x86.ActiveCfg = Release|Any CPU + {530E3032-F7CE-4EB2-9F21-B7D46331B9E6}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -716,8 +730,8 @@ Global {ECF7FC70-A7FC-4FC3-9BF7-462EA0A65F9C} = {2A381C57-2697-427B-9F10-55DA11FD02E4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} - RESX_PrefixTranslations = True RESX_NeutralResourcesLanguage = en-US + RESX_PrefixTranslations = True + SolutionGuid = {089687FD-5D25-40AB-BA8A-A10D1E137F98} EndGlobalSection EndGlobal diff --git a/FreeSql/DataType.cs b/FreeSql/DataType.cs index a8b3ef86..2a54f41e 100644 --- a/FreeSql/DataType.cs +++ b/FreeSql/DataType.cs @@ -67,6 +67,8 @@ namespace FreeSql /// /// 天津南大通用数据技术股份有限公司成立于2004年,是国产数据库、大数据领域的知名企业,基于 Odbc 的实现 /// - GBase + GBase, + + CustomOracle, CustomSqlServer, CustomMySql, CustomPostgreSQL } } diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 77c9363b..3dd3dbbd 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -309,6 +309,26 @@ namespace FreeSql if (type == null) throwNotFind("FreeSql.Provider.GBase.dll", "FreeSql.GBase.GBaseProvider<>"); break; + case DataType.CustomOracle: + type = Type.GetType("FreeSql.Custom.Oracle.CustomOracleProvider`1,FreeSql.Provider.Custom")?.MakeGenericType(typeof(TMark)); + if (type == null) throwNotFind("FreeSql.Provider.Custom.dll", "FreeSql.Custom.Oracle.CustomOracleProvider<>"); + break; + + case DataType.CustomSqlServer: + type = Type.GetType("FreeSql.Custom.SqlServer.CustomSqlServerProvider`1,FreeSql.Provider.Custom")?.MakeGenericType(typeof(TMark)); + if (type == null) throwNotFind("FreeSql.Provider.Custom.dll", "FreeSql.Custom.SqlServer.CustomSqlServerProvider<>"); + break; + + case DataType.CustomMySql: + type = Type.GetType("FreeSql.Custom.MySql.CustomMySqlProvider`1,FreeSql.Provider.Custom")?.MakeGenericType(typeof(TMark)); + if (type == null) throwNotFind("FreeSql.Provider.Custom.dll", "FreeSql.Custom.MySql.CustomMySqlProvider<>"); + break; + + case DataType.CustomPostgreSQL: + type = Type.GetType("FreeSql.Custom.PostgreSQL.CustomPostgreSQLProvider`1,FreeSql.Provider.Custom")?.MakeGenericType(typeof(TMark)); + if (type == null) throwNotFind("FreeSql.Provider.Custom.dll", "FreeSql.Custom.PostgreSQL.CustomPostgreSQLProvider<>"); + break; + default: throw new Exception(CoreStrings.NotSpecified_UseConnectionString_UseConnectionFactory); } } diff --git a/Providers/FreeSql.Provider.Custom/CustomProvider.cs b/Providers/FreeSql.Provider.Custom/CustomProvider.cs index ea8c315e..ce223f39 100644 --- a/Providers/FreeSql.Provider.Custom/CustomProvider.cs +++ b/Providers/FreeSql.Provider.Custom/CustomProvider.cs @@ -77,6 +77,7 @@ namespace FreeSql.Custom finally { FreeSqlCustomAdapterGlobalExtensions._dicCustomAdater.TryRemove(Ado.Identifier, out var tryada); + FreeSqlCustomAdapterGlobalExtensions._dicDbProviderFactory.TryRemove(Ado.Identifier, out var trydbpf); } } } @@ -88,4 +89,8 @@ public static class FreeSqlCustomAdapterGlobalExtensions internal static ConcurrentDictionary _dicCustomAdater = new ConcurrentDictionary(); public static void SetCustomAdapter(this IFreeSql that, CustomAdapter adapter) => _dicCustomAdater.AddOrUpdate(that.Ado.Identifier, adapter, (fsql, old) => adapter); internal static CustomAdapter GetCustomAdapter(this IFreeSql that) => _dicCustomAdater.TryGetValue(that.Ado.Identifier, out var tryada) ? tryada : DefaultAdapter; + + internal static ConcurrentDictionary _dicDbProviderFactory = new ConcurrentDictionary(); + public static void SetDbProviderFactory(this IFreeSql that, DbProviderFactory factory) => _dicDbProviderFactory.AddOrUpdate(that.Ado.Identifier, factory, (fsql, old) => factory); + internal static DbProviderFactory GetDbProviderFactory(this IFreeSql that) => _dicDbProviderFactory.TryGetValue(that.Ado.Identifier, out var trydbpf) ? trydbpf : throw new Exception("需要先设置 fsql.SetDbProviderFactory(..) 方法"); } diff --git a/Providers/FreeSql.Provider.Custom/FreeSqlCustomGlobalExtensions.cs b/Providers/FreeSql.Provider.Custom/FreeSqlCustomGlobalExtensions.cs new file mode 100644 index 00000000..81bbf156 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/FreeSqlCustomGlobalExtensions.cs @@ -0,0 +1,39 @@ +public static partial class FreeSqlCustomGlobalExtensions +{ + + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + internal static string FormatCustomOracle(this string that, params object[] args) => _customOracleAdo.Addslashes(that, args); + static FreeSql.Custom.Oracle.CustomOracleAdo _customOracleAdo = new FreeSql.Custom.Oracle.CustomOracleAdo(); + + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + internal static string FormatCustomSqlServer(this string that, params object[] args) => _customSqlServerAdo.Addslashes(that, args); + static FreeSql.Custom.SqlServer.CustomSqlServerAdo _customSqlServerAdo = new FreeSql.Custom.SqlServer.CustomSqlServerAdo(); + + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + internal static string FormatCustomMySql(this string that, params object[] args) => _customMySqlAdo.Addslashes(that, args); + static FreeSql.Custom.MySql.CustomMySqlAdo _customMySqlAdo = new FreeSql.Custom.MySql.CustomMySqlAdo(); + + /// + /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 + /// + /// + /// + /// + internal static string FormatCustomPostgreSQL(this string that, params object[] args) => _customPostgreSQLAdo.Addslashes(that, args); + static FreeSql.Custom.PostgreSQL.CustomPostgreSQLAdo _customPostgreSQLAdo = new FreeSql.Custom.PostgreSQL.CustomPostgreSQLAdo(); +} diff --git a/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlDelete.cs b/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlDelete.cs new file mode 100644 index 00000000..90e4f204 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlDelete.cs @@ -0,0 +1,121 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Custom.MySql +{ + + class CustomMySqlDelete : Internal.CommonProvider.DeleteProvider + { + public CustomMySqlDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() + { + var ret = new List(); + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => + { + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(_orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) + { + this.ClearData(); + sbret.Clear(); + } + return ret; + } + +#if net40 +#else + async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) + { + var ret = new List(); + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => + { + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) + { + this.ClearData(); + sbret.Clear(); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlInsert.cs b/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlInsert.cs new file mode 100644 index 00000000..7feb66c6 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlInsert.cs @@ -0,0 +1,201 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using FreeSql.Internal.ObjectPool; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Custom.MySql +{ + + class CustomMySqlInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public CustomMySqlInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + internal bool InternalIsIgnoreInto = false; + internal IFreeSql InternalOrm => _orm; + internal TableInfo InternalTable => _table; + internal DbParameter[] InternalParams => _params; + internal DbConnection InternalConnection => _connection; + internal DbTransaction InternalTransaction => _transaction; + internal CommonUtils InternalCommonUtils => _commonUtils; + internal CommonExpression InternalCommonExpression => _commonExpression; + internal List InternalSource => _source; + internal Dictionary InternalIgnore => _ignore; + internal void InternalClearData() => ClearData(); + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + + + public override string ToSql() + { + if (InternalIsIgnoreInto == false) return base.ToSqlValuesOrSelectUnionAll(); + var sql = base.ToSqlValuesOrSelectUnionAll(); + return $"INSERT IGNORE INTO {sql.Substring(12)}"; + } + + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + Object poolConn = null; + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, "; SELECT LAST_INSERT_ID();", _commandTimeout), _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + var conn = _connection; + if (_transaction != null) conn = _transaction.Connection; + if (conn == null) + { + poolConn = _orm.Ado.MasterPool.Get(); + conn = poolConn.Value; + } + _orm.Ado.ExecuteNonQuery(conn, _transaction, CommandType.Text, sql, _commandTimeout, _params); + ret = long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(conn, _transaction, CommandType.Text, " SELECT LAST_INSERT_ID()", _commandTimeout)), out var trylng) ? trylng : 0; + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + if (poolConn != null) + _orm.Ado.MasterPool.Return(poolConn); + + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + Object poolConn = null; + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + var conn = _connection; + if (_transaction != null) conn = _transaction.Connection; + if (conn == null) + { + poolConn = _orm.Ado.MasterPool.Get(); + conn = poolConn.Value; + } + await _orm.Ado.ExecuteNonQueryAsync(conn, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); + ret = long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(conn, _transaction, CommandType.Text, " SELECT LAST_INSERT_ID()", _commandTimeout, null, cancellationToken)), out var trylng) ? trylng : 0; + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + if (poolConn != null) + _orm.Ado.MasterPool.Return(poolConn); + + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlInsertOrUpdate.cs b/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlInsertOrUpdate.cs new file mode 100644 index 00000000..bee35064 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlInsertOrUpdate.cs @@ -0,0 +1,88 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Text; + +namespace FreeSql.Custom.MySql +{ + + class CustomMySqlInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public CustomMySqlInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + var dbParams = new List(); + if (_sourceSql != null) + { + var data = new List(); + data.Add((T1)_table.Type.CreateInstanceGetDefaultValue()); + var sql = getInsertSql(data, false, false); + var sb = new StringBuilder(); + sb.Append(sql.Substring(0, sql.IndexOf(") VALUES"))); + sb.Append(") \r\n"); + WriteSourceSelectUnionAll(null, sb, null); + if (_doNothing == false) + sb.Append(sql.Substring(sql.IndexOf("\r\nON DUPLICATE KEY UPDATE\r\n") + 2)); + else + throw new Exception("Not implemented! fsql.InsertOrUpdate + SetSource(sql) + IfExistsDoNothing + MySql"); + return sb.ToString(); + } + if (_source?.Any() != true) return null; + + var sqls = new string[2]; + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = string.Join("\r\n\r\n;\r\n\r\n", ds.Item1.Select(a => getInsertSql(a, false, true))); + if (ds.Item2.Any()) sqls[1] = string.Join("\r\n\r\n;\r\n\r\n", ds.Item2.Select(a => getInsertSql(a, true, true))); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); + + string getInsertSql(List data, bool flagInsert, bool noneParameter) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(noneParameter) as Internal.CommonProvider.InsertProvider; + insert._source = data; + insert._table = _table; + insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; + + string sql = ""; + if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); + else + { + insert.InsertIdentity(); + if (_doNothing == false) + { + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + sql = new CustomMySqlOnDuplicateKeyUpdate(insert) + .UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()) + .ToSql(); + } + else + { + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.Entity_Must_Primary_Key("fsql.InsertOrUpdate + IfExistsDoNothing + MySql ", _table.CsName)); + sql = insert.ToSqlValuesOrSelectUnionAllExtension101(false, (rowd, idx, sb) => + sb.Append(" \r\n FROM dual WHERE NOT EXISTS(").Append( + _orm.Select() + .AsTable((_, __) => _tableRule?.Invoke(__)).AsType(_table.Type) + .DisableGlobalFilter() + .WhereDynamic(rowd) + .Limit(1).ToSql("1").Replace(" \r\n", " \r\n ")).Append(")")); + } + } + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlOnDuplicateKeyUpdate.cs b/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlOnDuplicateKeyUpdate.cs new file mode 100644 index 00000000..e67f1c85 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlOnDuplicateKeyUpdate.cs @@ -0,0 +1,168 @@ +using FreeSql.Aop; +using System; +using System.Data; +using System.Linq.Expressions; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Custom.MySql +{ + public class CustomMySqlOnDuplicateKeyUpdate where T1 : class + { + internal CustomMySqlInsert _mysqlInsert; + internal CustomMySqlUpdate _mysqlUpdatePriv; + internal CustomMySqlUpdate _mysqlUpdate => _mysqlUpdatePriv ?? (_mysqlUpdatePriv = new CustomMySqlUpdate(_mysqlInsert.InternalOrm, _mysqlInsert.InternalCommonUtils, _mysqlInsert.InternalCommonExpression, null).NoneParameter().SetSource(_mysqlInsert.InternalSource) as CustomMySqlUpdate); + + public CustomMySqlOnDuplicateKeyUpdate(IInsert insert) + { + _mysqlInsert = insert as CustomMySqlInsert; + if (_mysqlInsert == null) throw new Exception(CoreStrings.S_Features_Unique("OnDuplicateKeyUpdate", "Odbc/MySql")); + if (_mysqlInsert._noneParameterFlag == "c") _mysqlInsert._noneParameterFlag = "cu"; + } + + protected void ClearData() + { + _mysqlInsert.InternalClearData(); + _mysqlUpdatePriv = null; + } + + public CustomMySqlOnDuplicateKeyUpdate IgnoreColumns(Expression> columns) + { + _mysqlUpdate.IgnoreColumns(columns); + return this; + } + public CustomMySqlOnDuplicateKeyUpdate UpdateColumns(Expression> columns) + { + _mysqlUpdate.UpdateColumns(columns); + return this; + } + public CustomMySqlOnDuplicateKeyUpdate IgnoreColumns(string[] columns) + { + _mysqlUpdate.IgnoreColumns(columns); + return this; + } + public CustomMySqlOnDuplicateKeyUpdate UpdateColumns(string[] columns) + { + _mysqlUpdate.UpdateColumns(columns); + return this; + } + + public CustomMySqlOnDuplicateKeyUpdate Set(Expression> column, TMember value) + { + _mysqlUpdate.Set(column, value); + return this; + } + public CustomMySqlOnDuplicateKeyUpdate Set(Expression> exp) + { + _mysqlUpdate.Set(exp); + return this; + } + public CustomMySqlOnDuplicateKeyUpdate SetRaw(string sql) + { + _mysqlUpdate.SetRaw(sql); + return this; + } + + public string ToSql() + { + var sb = new StringBuilder(); + sb.Append(_mysqlInsert.ToSql()).Append("\r\nON DUPLICATE KEY UPDATE\r\n"); + + var sbSetEmpty = _mysqlUpdate.InternalSbSet.Length == 0; + var sbSetIncrEmpty = _mysqlUpdate.InternalSbSetIncr.Length == 0; + if (sbSetEmpty == false || sbSetIncrEmpty == false) + { + if (sbSetEmpty == false) sb.Append(_mysqlUpdate.InternalSbSet.ToString().Substring(2)); + if (sbSetIncrEmpty == false) sb.Append(sbSetEmpty ? _mysqlUpdate.InternalSbSetIncr.ToString().Substring(2) : _mysqlUpdate.InternalSbSetIncr.ToString()); + } + else + { + var colidx = 0; + foreach (var col in _mysqlInsert.InternalTable.Columns.Values) + { + if (col.Attribute.IsPrimary || _mysqlUpdate.InternalIgnore.ContainsKey(col.Attribute.Name)) continue; + + if (colidx > 0) sb.Append(", \r\n"); + + if (col.Attribute.IsVersion == true && col.Attribute.MapType != typeof(byte[])) + { + var field = _mysqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = ").Append(field).Append(" + 1"); + } + else if (_mysqlInsert.InternalIgnore.ContainsKey(col.Attribute.Name)) + { + var caseWhen = _mysqlUpdate.InternalWhereCaseSource(col.CsName, sqlval => sqlval).Trim(); + sb.Append(caseWhen); + if (caseWhen.EndsWith(" END")) _mysqlUpdate.InternalToSqlCaseWhenEnd(sb, col); + } + else + { + var field = _mysqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = VALUES(").Append(field).Append(")"); + } + ++colidx; + } + } + + return sb.ToString(); + } + + public long ExecuteAffrows() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_mysqlInsert.InternalTable.Type, _mysqlInsert.InternalTable, CurdType.Insert, sql, _mysqlInsert.InternalParams); + _mysqlInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_mysqlInsert, before); + long ret = 0; + Exception exception = null; + try + { + ret = _mysqlInsert.InternalOrm.Ado.ExecuteNonQuery(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert._commandTimeout, _mysqlInsert.InternalParams); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _mysqlInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_mysqlInsert, after); + ClearData(); + } + return ret; + } + +#if net40 +#else + async public Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_mysqlInsert.InternalTable.Type, _mysqlInsert.InternalTable, CurdType.Insert, sql, _mysqlInsert.InternalParams); + _mysqlInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_mysqlInsert, before); + long ret = 0; + Exception exception = null; + try + { + ret = await _mysqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_mysqlInsert.InternalConnection, _mysqlInsert.InternalTransaction, CommandType.Text, sql, _mysqlInsert._commandTimeout, _mysqlInsert.InternalParams, cancellationToken); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _mysqlInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_mysqlInsert, after); + ClearData(); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlSelect.cs b/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlSelect.cs new file mode 100644 index 00000000..4a7cf054 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlSelect.cs @@ -0,0 +1,212 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Custom.MySql +{ + + class CustomMySqlSelect : FreeSql.Internal.CommonProvider.Select1Provider + { + + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereGlobalFilter.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field).Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); + } + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + switch (tb.Type) + { + case SelectTableInfoType.Parent: + case SelectTableInfoType.RawJoin: + continue; + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND ").Append(_tables[0].Cascade); + + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + if (_skip > 0 || _limit > 0) + sb.Append(" \r\nlimit ").Append(Math.Max(0, _skip)).Append(",").Append(_limit > 0 ? _limit : -1); + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.Append(_tosqlAppendContent).ToString(); + } + + public CustomMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); CustomMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); CustomMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); CustomMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); CustomMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); CustomMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); CustomMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); CustomMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); CustomMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); CustomMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); CustomMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); CustomMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); CustomMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); CustomMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); CustomMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcMySqlSelect(_orm, _commonUtils, _commonExpression, null); CustomMySqlSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcMySqlSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public OdbcMySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomMySqlSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } +} diff --git a/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlUpdate.cs b/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlUpdate.cs new file mode 100644 index 00000000..8a1900f4 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlUpdate.cs @@ -0,0 +1,170 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Custom.MySql +{ + + class CustomMySqlUpdate : Internal.CommonProvider.UpdateProvider + { + + public CustomMySqlUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + internal StringBuilder InternalSbSet => _set; + internal StringBuilder InternalSbSetIncr => _setIncr; + internal Dictionary InternalIgnore => _ignore; + internal void InternalResetSource(List source) => _source = source; + internal string InternalWhereCaseSource(string CsName, Func thenValue) => WhereCaseSource(CsName, thenValue); + internal void InternalToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) => ToSqlCaseWhenEnd(sb, col); + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + + protected override List RawExecuteUpdated() + { + var ret = new List(); + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => + { + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); + return ret; + } + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (primarys.Length == 1) + { + var pk = primarys.First(); + caseWhen.Append(_commonUtils.RereadColumn(pk, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + return; + } + caseWhen.Append("CONCAT("); + var pkidx = 0; + foreach (var pk in primarys) + { + if (pkidx > 0) caseWhen.Append(", '+', "); + caseWhen.Append(_commonUtils.RereadColumn(pk, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", primarys[0].GetDbValue(d))); + return; + } + sb.Append("CONCAT("); + var pkidx = 0; + foreach (var pk in primarys) + { + if (pkidx > 0) sb.Append(", '+', "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))); + ++pkidx; + } + sb.Append(")"); + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + + async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) + { + var ret = new List(); + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => + { + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlAdo/CustomMySqlAdo.cs b/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlAdo/CustomMySqlAdo.cs new file mode 100644 index 00000000..45134b18 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlAdo/CustomMySqlAdo.cs @@ -0,0 +1,68 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using FreeSql.Internal.ObjectPool; +using System; +using System.Collections; +using System.Data.Common; +using System.Text; +using System.Threading; + +namespace FreeSql.Custom.MySql +{ + public class CustomMySqlAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + DbProviderFactory Factory => FreeSqlCustomAdapterGlobalExtensions.GetDbProviderFactory(_util._orm); + + public CustomMySqlAdo() : base(DataType.OdbcMySql, null, null) { } + public CustomMySqlAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcMySql, masterConnectionString, slaveConnectionStrings) + { + base._util = util; + if (connectionFactory != null) + { + var pool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.SqlServer, connectionFactory); + MasterPool = pool; + return; + } + throw new Exception(CoreStrings.S_CustomAdapter_OnlySuppport_UseConnectionFactory); + } + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) + param = Utils.GetDataReaderValue(mapType, param); + + if (param is bool || param is bool?) + return (bool)param ? 1 : 0; + else if (param is string) + return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\"), "'"); //只有 mysql 需要处理反斜杠 + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\").Replace('\0', ' '), "'"); + else if (param is Enum) + return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\").Replace(", ", ","), "'"); //((Enum)val).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.fff"), "'"); + else if (param is TimeSpan || param is TimeSpan?) + return ((TimeSpan)param).Ticks / 10; + else if (param is byte[]) + return $"0x{CommonUtils.BytesSqlRaw(param as byte[])}"; + else if (param is IEnumerable) + return AddslashesIEnumerable(param, mapType, mapColumn); + + return string.Concat("'", param.ToString().Replace("'", "''").Replace("\\", "\\\\"), "'"); + } + + public override DbCommand CreateCommand() + { + return Factory.CreateCommand(); + } + + public override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) + { + pool.Return(conn); + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} diff --git a/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlCodeFirst.cs new file mode 100644 index 00000000..8cce49e2 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlCodeFirst.cs @@ -0,0 +1,408 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using FreeSql.Internal.ObjectPool; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Custom.MySql +{ + + class CustomMySqlCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; } + public CustomMySqlCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + + static object _dicCsToDbLock = new object(); + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(bool).FullName, CsToDb.New(DbType.Boolean, "bit","bit(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(DbType.Boolean, "bit","bit(1)", null, true, null) }, + + { typeof(sbyte).FullName, CsToDb.New(DbType.SByte, "tinyint", "tinyint(3) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(DbType.SByte, "tinyint", "tinyint(3)", false, true, null) }, + { typeof(short).FullName, CsToDb.New(DbType.Int16, "smallint","smallint(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(DbType.Int16, "smallint", "smallint(6)", false, true, null) }, + { typeof(int).FullName, CsToDb.New(DbType.Int32, "int", "int(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(DbType.Int32, "int", "int(11)", false, true, null) }, + { typeof(long).FullName, CsToDb.New(DbType.Int64, "bigint","bigint(20) NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(DbType.Int64, "bigint","bigint(20)", false, true, null) }, + + { typeof(byte).FullName, CsToDb.New(DbType.Byte, "tinyint","tinyint(3) unsigned NOT NULL", true, false, 0) },{ typeof(byte?).FullName, CsToDb.New(DbType.Byte, "tinyint","tinyint(3) unsigned", true, true, null) }, + { typeof(ushort).FullName, CsToDb.New(DbType.UInt16, "smallint","smallint(5) unsigned NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(DbType.UInt16, "smallint", "smallint(5) unsigned", true, true, null) }, + { typeof(uint).FullName, CsToDb.New(DbType.UInt32, "int", "int(10) unsigned NOT NULL", true, false, 0) },{ typeof(uint?).FullName, CsToDb.New(DbType.UInt32, "int", "int(10) unsigned", true, true, null) }, + { typeof(ulong).FullName, CsToDb.New(DbType.UInt64, "bigint", "bigint(20) unsigned NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(DbType.UInt64, "bigint", "bigint(20) unsigned", true, true, null) }, + + { typeof(double).FullName, CsToDb.New(DbType.Double, "double", "double NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(DbType.Double, "double", "double", false, true, null) }, + { typeof(float).FullName, CsToDb.New(DbType.Single, "float","float NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(DbType.Single, "float","float", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(DbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(DbType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, + + { typeof(TimeSpan).FullName, CsToDb.New(DbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(DbType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(DbType.DateTime, "datetime(3)", "datetime(3) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(DbType.DateTime, "datetime(3)", "datetime(3)", false, true, null) }, + + { typeof(byte[]).FullName, CsToDb.New(DbType.Binary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, + { typeof(string).FullName, CsToDb.New(DbType.String, "varchar", "varchar(255)", false, null, "") }, + { typeof(char).FullName, CsToDb.New(DbType.AnsiString, "char", "char(1) NULL", false, null, '\0') }, + + { typeof(Guid).FullName, CsToDb.New(DbType.Guid, "char", "char(36) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(DbType.Guid, "char", "char(36)", false, true, null) }, + }; + + public override DbInfoResult GetDbInfo(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } + if (enumType != null) + { + var names = string.Join(",", Enum.GetNames(enumType).Select(a => _commonUtils.FormatSql("{0}", a))); + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + CsToDb.New(DbType.String, "set", $"set({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(DbType.String, "enum", $"enum({names}){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue); + } + return null; + } + + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) + { + Object conn = null; + string database = null; + + try + { + conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); + database = conn.Value.Database; + + var sb = new StringBuilder(); + foreach (var obj in objects) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception(CoreStrings.S_Type_IsNot_Migrable(obj.entityType.FullName)); + if (tb.Columns.Any() == false) throw new Exception(CoreStrings.S_Type_IsNot_Migrable_0Attributes(obj.entityType.FullName)); + var tbname = _commonUtils.SplitTableName(tb.DbName); + if (tbname?.Length == 1) tbname = new[] { database, tbname[0] }; + + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { database, tboldname[0] }; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); + if (tbtmpname?.Length == 1) tbtmpname = new[] { database, tbtmpname[0] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) + { + tbname = tbtmpname; + tboldname = null; + } + } + + if (string.Compare(tbname[0], database, true) != 0 && LocalExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tbname[0])) == null) //创建数据库 + sb.Append($"CREATE DATABASE IF NOT EXISTS ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(" default charset utf8 COLLATE utf8_general_ci;\r\n"); + + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (LocalExecuteScalar(tbname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tbname)) == null) + { //表不存在 + if (tboldname != null) + { + if (string.Compare(tboldname[0], tbname[0], true) != 0 && LocalExecuteScalar(database, _commonUtils.FormatSql(" select 1 from information_schema.schemata where schema_name={0}", tboldname[0])) == null || + LocalExecuteScalar(tboldname[0], _commonUtils.FormatSql(" SELECT 1 FROM information_schema.TABLES WHERE table_schema={0} and table_name={1}", tboldname)) == null) + //数据库或表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建表 + var createTableName = _commonUtils.QuoteSqlName(tbname[0], tbname[1]); + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)); + sb.Append(","); + } + if (tb.Primarys.Any()) + { + 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("),"); + } + //创建表的索引,感谢 @mafeng8,这样写可以支持自增不是主键的情况 + foreach (var uk in tb.Indexes) + { + sb.Append(" \r\n "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) Engine=InnoDB"); + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append(" Comment=").Append(_commonUtils.FormatSql("{0}", tb.Comment)); + sb.Append(";\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 sql = _commonUtils.FormatSql(@" +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', +a.column_comment 'comment' +from information_schema.columns a +where a.table_schema in ({0}) and a.table_name in ({1})", tboldname ?? tbname); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => + { + var a1 = string.Concat(a[1]); + if (a1 == "datetime") a1 = string.Concat(a1, "(0)"); + return new + { + column = string.Concat(a[0]), + sqlType = a1, + is_nullable = string.Concat(a[2]) == "1", + is_identity = string.Concat(a[3]) == "1", + is_unsigned = string.Concat(a[1]).EndsWith(" unsigned"), + comment = string.Concat(a[4]) + }; + }, StringComparer.CurrentCultureIgnoreCase); + + if (istmpatler == false) + { + var existsPrimary = LocalExecuteScalar(tbname[0], _commonUtils.FormatSql(" select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1", tbname)); + foreach (var tbcol in tb.ColumnsByPosition) + { + var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + var isDbTypeChanged = tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false; + if (tbstructcol.sqlType == "datetime(0)" && Regex.IsMatch(tbcol.Attribute.DbType, @"datetime\s*\(", RegexOptions.IgnoreCase) == false) + isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("datetime", StringComparison.CurrentCultureIgnoreCase) == false; + else if (tbstructcol.sqlType.StartsWith("datetime", StringComparison.CurrentCultureIgnoreCase)) isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("datetime", StringComparison.CurrentCultureIgnoreCase) == false || + (int.TryParse(Regex.Match(tbcol.Attribute.DbType, @"datetime\s*\((\d*)", RegexOptions.IgnoreCase).Groups[1].Value, out var trydtrd) ? trydtrd : 3) != + (int.TryParse(Regex.Match(tbstructcol.sqlType, @"datetime\s*\((\d*)", RegexOptions.IgnoreCase).Groups[1].Value, out var trydtrd2) ? trydtrd2 : 3); + else if (tbstructcol.sqlType.StartsWith("int", StringComparison.CurrentCultureIgnoreCase)) isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("int", StringComparison.CurrentCultureIgnoreCase) == false; + else if (tbstructcol.sqlType.StartsWith("tinyint", StringComparison.CurrentCultureIgnoreCase)) isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("tinyint", StringComparison.CurrentCultureIgnoreCase) == false; + else if (tbstructcol.sqlType.StartsWith("smallint", StringComparison.CurrentCultureIgnoreCase)) isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("smallint", StringComparison.CurrentCultureIgnoreCase) == false; + else if (tbstructcol.sqlType.StartsWith("bigint", StringComparison.CurrentCultureIgnoreCase)) isDbTypeChanged = tbcol.Attribute.DbType.StartsWith("bigint", StringComparison.CurrentCultureIgnoreCase) == false; + + if ((tbcol.Attribute.DbType.IndexOf(" unsigned", StringComparison.CurrentCultureIgnoreCase) != -1) != tbstructcol.is_unsigned || + isDbTypeChanged || + tbcol.Attribute.IsNullable != tbstructcol.is_nullable || + tbcol.Attribute.IsIdentity != tbstructcol.is_identity || + isCommentChanged) + { + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable && tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.DbType); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" AUTO_INCREMENT"); + if (tbcol.Attribute.IsIdentity == true) sbalter.Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); + sbalter.Append(";\r\n"); + } + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + { + //修改列名 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(" CHANGE COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" AUTO_INCREMENT"); + if (tbcol.Attribute.IsIdentity == true) sbalter.Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); + 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.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) sbalter.Append(" DEFAULT ").Append(tbcol.DbDefaultValue); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "")); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" AUTO_INCREMENT"); + if (tbcol.Attribute.IsIdentity == true) sbalter.Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); + sbalter.Append(";\r\n"); + } + var dsuksql = _commonUtils.FormatSql(@" +select +a.column_name, +a.index_name 'index_id', +0 'IsDesc', +case when a.non_unique = 0 then 1 else 0 end 'IsUnique' +from information_schema.statistics a +where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRIMARY'", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); + foreach (var uk in tb.Indexes) + { + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var ukname = ReplaceIndexName(uk.Name, tbname[1]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) + { + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(";\r\n"); + sbalter.Append("CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } + sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); + } + } + } + if (istmpatler == false) + { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select table_comment from information_schema.tables where table_schema = {0} and table_name = {1}", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(" COMMENT ").Append(" ").Append(_commonUtils.FormatSql("{0}", tb.Comment ?? "")).Append(";\r\n"); + + sb.Insert(0, 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.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append(" COMMENT ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)); + sb.Append(","); + } + if (tb.Primarys.Any()) + { + 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.Remove(sb.Length - 1, 1); + sb.Append("\r\n) Engine=InnoDB"); + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append(" Comment=").Append(_commonUtils.FormatSql("{0}", tb.Comment)); + sb.Append(";\r\n"); + + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.ColumnsByPosition) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.ColumnsByPosition) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { + //insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; + } + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"ifnull({insertvalue},{tbcol.DbDefaultValue})"; + } + else if (tbcol.Attribute.IsNullable == false) + if (tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) + insertvalue = tbcol.DbDefaultValue; + 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"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } + } + return sb.Length == 0 ? null : sb.ToString(); + } + finally + { + try + { + if (string.IsNullOrEmpty(database) == false) + conn.Value.ChangeDatabase(database); + _orm.Ado.MasterPool.Return(conn); + } + catch + { + _orm.Ado.MasterPool.Return(conn, true); + } + } + + object LocalExecuteScalar(string db, string sql) + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); + 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); + } + } + } + + public override int ExecuteDDLStatements(string ddl) + { + if (string.IsNullOrEmpty(ddl)) return 0; + var scripts = ddl.Split(new string[] { ";\r\n" }, StringSplitOptions.None).Where(a => string.IsNullOrEmpty(a.Trim()) == false).ToArray(); + + if (scripts.Any() == false) return 0; + + var affrows = 0; + foreach (var script in scripts) + affrows += base.ExecuteDDLStatements(script); + return affrows; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlDbFirst.cs b/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlDbFirst.cs new file mode 100644 index 00000000..6a90d2d5 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlDbFirst.cs @@ -0,0 +1,457 @@ +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Custom.MySql +{ + class CustomMySqlDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public CustomMySqlDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column); + DbType GetSqlDbType(DbColumnInfo column) + { + var is_unsigned = column.DbTypeTextFull?.ToLower().EndsWith(" unsigned") == true; + switch (column.DbTypeText?.ToLower()) + { + case "bit": return DbType.Boolean; + + case "tinyint": return is_unsigned ? DbType.Byte : DbType.SByte; + case "smallint": return is_unsigned ? DbType.Int16 : DbType.Int16; + case "mediumint": return is_unsigned ? DbType.Int32 : DbType.Int32; + case "int": return is_unsigned ? DbType.Int32 : DbType.Int32; + case "bigint": return is_unsigned ? DbType.UInt64 : DbType.Int64; + + case "real": + case "double": return DbType.Double; + case "float": return DbType.Single; + case "numeric": + case "decimal": return DbType.Decimal; + + case "year": return DbType.Int32; + case "time": return DbType.Time; + case "date": return DbType.Date; + case "timestamp": return DbType.DateTime; + case "datetime": return DbType.DateTime; + + case "tinyblob": return DbType.Binary; + case "blob": return DbType.Binary; + case "mediumblob": return DbType.Binary; + case "longblob": return DbType.Binary; + + case "binary": return DbType.Binary; + case "varbinary": return DbType.Binary; + + case "tinytext": return DbType.String; + case "text": return DbType.String; + case "mediumtext": return DbType.String; + case "longtext": return DbType.String; + + case "char": return column.MaxLength == 36 ? DbType.Guid : DbType.AnsiString; + case "varchar": return DbType.String; + + case "set": return DbType.String; + case "enum": return DbType.String; + + default: return DbType.String; + } + } + + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)DbType.Boolean, new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + + { (int)DbType.SByte, new DbToCs("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetInt16") }, + { (int)DbType.Int16, new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)DbType.Int32, new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)DbType.Int64, new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + + { (int)DbType.Byte, new DbToCs("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { (int)DbType.UInt16, new DbToCs("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") }, + { (int)DbType.UInt32, new DbToCs("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") }, + { (int)DbType.UInt64, new DbToCs("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetInt64") }, + + { (int)DbType.Double, new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { (int)DbType.Single, new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)DbType.Decimal, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + + { (int)DbType.Time, new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { (int)DbType.Date, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)DbType.DateTime, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + + { (int)DbType.Binary, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + { (int)DbType.String, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + + { (int)DbType.AnsiString, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)DbType.Guid, new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, + }; + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + var sql = @" select schema_name from information_schema.schemata where schema_name not in ('information_schema', 'mysql', 'performance_schema')"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); + } + + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) + { + var database = ""; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + database = conn.Value.Database; + } + tbname = new[] { database, tbname[0] }; + } + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $" SELECT 1 FROM information_schema.TABLES WHERE {(ignoreCase ? "lower(table_schema)" : "table_schema")} = {_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(table_name)" : "table_name")} = {_commonUtils.FormatSql("{0}", tbname[1])}"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) + { + var loc1 = new List(); + var loc2 = new Dictionary(StringComparer.CurrentCultureIgnoreCase); + var loc3 = new Dictionary>(StringComparer.CurrentCultureIgnoreCase); + string[] tbname = null; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) + { + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + if (string.IsNullOrEmpty(conn.Value.Database)) return loc1; + tbname = new[] { conn.Value.Database, tbname[0] }; + } + } + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + database = new[] { tbname[0] }; + } + else if (database == null || database.Any() == false) + { + using (var conn = _orm.Ado.MasterPool.Get()) + { + if (string.IsNullOrEmpty(conn.Value.Database)) return loc1; + database = new[] { conn.Value.Database }; + } + } + + var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); + var sql = $@" +select +concat(a.table_schema, '.', a.table_name) 'id', +a.table_schema 'schema', +a.table_name 'table', +a.table_comment, +a.table_type 'type' +from information_schema.tables a +where {(ignoreCase ? "lower(a.table_schema)" : "a.table_schema")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.table_name)" : "a.table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); + foreach (var row in ds) + { + var table_id = string.Concat(row[0]); + var schema = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + var type = string.Concat(row[4]) == "VIEW" ? DbTableType.VIEW : DbTableType.TABLE; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + schema = ""; + } + loc2.Add(table_id, new DbTableInfo { Id = table_id, Schema = schema, Name = table, Comment = comment, Type = type }); + loc3.Add(table_id, new Dictionary(StringComparer.CurrentCultureIgnoreCase)); + switch (type) + { + case DbTableType.TABLE: + case DbTableType.VIEW: + loc6_1000.Add(table.Replace("'", "''")); + if (loc6_1000.Count >= 500) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } + break; + case DbTableType.StoreProcedure: + loc66_1000.Add(table.Replace("'", "''")); + if (loc66_1000.Count >= 500) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } + break; + } + } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + + if (loc6.Count == 0) return loc1; + var loc8 = new StringBuilder().Append("("); + for (var loc8idx = 0; loc8idx < loc6.Count; loc8idx++) + { + if (loc8idx > 0) loc8.Append(" OR "); + loc8.Append("a.table_name in ("); + for (var loc8idx2 = 0; loc8idx2 < loc6[loc8idx].Length; loc8idx2++) + { + if (loc8idx2 > 0) loc8.Append(","); + loc8.Append($"'{loc6[loc8idx][loc8idx2]}'"); + } + loc8.Append(")"); + } + loc8.Append(")"); + + sql = $@" +select +concat(a.table_schema, '.', a.table_name), +a.column_name, +a.data_type, +ifnull(a.character_maximum_length, 0) 'len', +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', +a.column_comment 'comment', +a.column_default 'default_value', +a.ordinal_position +from information_schema.columns a +where {(ignoreCase ? "lower(a.table_schema)" : "a.table_schema")} in ({databaseIn}) and {loc8} +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string type = string.Concat(row[2]); + //long max_length = long.Parse(string.Concat(row[3])); + string sqlType = string.Concat(row[4]); + var m_len = Regex.Match(sqlType, @"\w+\((\d+)"); + int max_length = m_len.Success ? int.Parse(m_len.Groups[1].Value) : -1; + bool is_nullable = string.Concat(row[5]) == "1"; + bool is_identity = string.Concat(row[6]) == "1"; + string comment = string.Concat(row[7]); + string defaultValue = string.Concat(row[8]); + var position = int.Parse(string.Concat(row[9])); + + if (max_length == 0) max_length = -1; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + } + loc3[table_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[table_id], + Comment = comment, + DefaultValue = defaultValue, + Position = position + }); + loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); + loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); + } + + sql = $@" +select +concat(a.table_schema, '.', a.table_name) 'table_id', +a.column_name, +a.index_name 'index_id', +case when a.non_unique = 0 then 1 else 0 end 'IsUnique', +case when a.index_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey', +0 'IsClustered', +0 'IsDesc' +from information_schema.statistics a +where {(ignoreCase ? "lower(a.table_schema)" : "a.table_schema")} in ({databaseIn}) and {loc8} +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var indexColumns = new Dictionary>(StringComparer.CurrentCultureIgnoreCase); + var uniqueColumns = new Dictionary>(StringComparer.CurrentCultureIgnoreCase); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string index_id = string.Concat(row[2]); + bool is_unique = string.Concat(row[3]) == "1"; + bool is_primary_key = string.Concat(row[4]) == "1"; + bool is_clustered = string.Concat(row[5]) == "1"; + bool is_desc = string.Concat(row[6]) == "1"; + if (database.Length == 1) + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + + Dictionary loc10 = null; + DbIndexInfo loc11 = null; + if (!indexColumns.TryGetValue(table_id, out loc10)) + indexColumns.Add(table_id, loc10 = new Dictionary(StringComparer.CurrentCultureIgnoreCase)); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(table_id, out loc10)) + uniqueColumns.Add(table_id, loc10 = new Dictionary(StringComparer.CurrentCultureIgnoreCase)); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + } + } + foreach (string table_id in indexColumns.Keys) + { + foreach (var column in indexColumns[table_id]) + loc2[table_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (string table_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[table_id]) + { + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); + loc2[table_id].UniquesDict.Add(column.Key, column.Value); + } + } + + if (tbname == null) + { + sql = $@" +select +concat(a.constraint_schema, '.', a.table_name) 'table_id', +a.column_name, +a.constraint_name 'FKId', +concat(a.referenced_table_schema, '.', a.referenced_table_name) 'ref_table_id', +1 'IsForeignKey', +a.referenced_column_name 'ref_column' +from information_schema.key_column_usage a +where {(ignoreCase ? "lower(a.constraint_schema)" : "a.constraint_schema")} in ({databaseIn}) and {loc8} and not isnull(position_in_unique_constraint) +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var fkColumns = new Dictionary>(StringComparer.CurrentCultureIgnoreCase); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + string ref_table_id = string.Concat(row[3]); + bool is_foreign_key = string.Concat(row[4]) == "1"; + string referenced_column = string.Concat(row[5]); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; + + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary(StringComparer.CurrentCultureIgnoreCase)); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + } + + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); + + loc2.Clear(); + loc3.Clear(); + return loc1; + } + + public List GetEnumsByDatabase(params string[] database) + { + return new List(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlExpression.cs b/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlExpression.cs new file mode 100644 index 00000000..a50190b1 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlExpression.cs @@ -0,0 +1,563 @@ +using FreeSql.Internal; +using System; +using System.Collections; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Custom.MySql +{ + class CustomMySqlExpression : CommonExpression + { + + public CustomMySqlExpression(CommonUtils common) : base(common) { } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + if (arrOper.Type == typeof(byte[])) return $"octet_length({getExp(arrOper)})"; + break; + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (gentype.ToString()) + { + case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(operandExp)} as unsigned)"; + case "System.Char": return $"substr(cast({getExp(operandExp)} as char), 1, 1)"; + case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"cast({getExp(operandExp)} as datetime)"; + case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))"; + case "System.Double": return $"cast({getExp(operandExp)} as decimal(32,16))"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(operandExp)} as signed)"; + case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))"; + case "System.String": return $"cast({getExp(operandExp)} as char)"; + case "System.UInt16": + case "System.UInt32": + case "System.UInt64": return $"cast({getExp(operandExp)} as unsigned)"; + case "System.Guid": return $"substr(cast({getExp(operandExp)} as char), 1, 36)"; + } + } + break; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as unsigned)"; + case "System.Char": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 1)"; + case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"cast({getExp(callExp.Arguments[0])} as datetime)"; + case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))"; + case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(32,16))"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as signed)"; + case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as decimal(14,7))"; + case "System.UInt16": + case "System.UInt32": + case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as unsigned)"; + case "System.Guid": return $"substr(cast({getExp(callExp.Arguments[0])} as char), 1, 36)"; + } + return null; + case "NewGuid": + return null; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "cast(rand()*1000000000 as signed)"; + return null; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "rand()"; + return null; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; + return null; + case "ToString": + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"cast({getExp(callExp.Object)} as char)" : null; + return null; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substr({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArrayOrList()) + { + if (argIndex >= callExp.Arguments.Count) break; + tsc.SetMapColumnTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = objExp?.NodeType == ExpressionType.MemberAccess ? tsc.SetDbParamsReturnOld(null) : null; //#900 UseGenerateCommandParameterWithLambda(true) 子查询 bug、以及 #1173 参数化 bug + tsc.isNotSetMapColumnTmp = true; + var left = objExp == null ? null : getExp(objExp); + tsc.isNotSetMapColumnTmp = false; + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + if (oldDbParams != null) tsc.SetDbParamsReturnOld(oldDbParams); + switch (callExp.Method.Name) + { + case "Contains": + //判断 in //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("("); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + if (a % 500 == 499) arrSb.Append(" \r\n \r\n"); //500元素分割, 3空格\r\n4空格 + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append(")").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"char_length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; + case "Today": return "curdate()"; + case "MinValue": return "cast('0001/1/1 0:00:00' as datetime)"; + case "MaxValue": return "cast('9999/12/31 23:59:59' as datetime)"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"cast(date_format({left},'%Y-%m-%d') as datetime)"; + case "TimeOfDay": return $"timestampdiff(microsecond, date_format({left},'%Y-%m-%d'), {left})"; + case "DayOfWeek": return $"(dayofweek({left})-1)"; + case "Day": return $"dayofmonth({left})"; + case "DayOfYear": return $"dayofyear({left})"; + case "Month": return $"month({left})"; + case "Year": return $"year({left})"; + case "Hour": return $"hour({left})"; + case "Minute": return $"minute({left})"; + case "Second": return $"second({left})"; + case "Millisecond": return $"floor(microsecond({left})/1000)"; + case "Ticks": return $"(timestampdiff(microsecond, '0001-1-1', {left})*10)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 + case "MaxValue": return "922337203685477580"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"(({left}) div {(long)1000000 * 60 * 60 * 24})"; + case "Hours": return $"(({left}) div {(long)1000000 * 60 * 60} mod 24)"; + case "Milliseconds": return $"(({left}) div 1000 mod 1000)"; + case "Minutes": return $"(({left}) div {(long)1000000 * 60} mod 60)"; + case "Seconds": return $"(({left}) div 1000000 mod 60)"; + case "Ticks": return $"(({left}) * 10)"; + case "TotalDays": return $"(({left}) / {(long)1000000 * 60 * 60 * 24})"; + case "TotalHours": return $"(({left}) / {(long)1000000 * 60 * 60})"; + case "TotalMilliseconds": return $"(({left}) / 1000)"; + case "TotalMinutes": return $"(({left}) / {(long)1000000 * 60})"; + case "TotalSeconds": return $"(({left}) / 1000000)"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception(CoreStrings.Not_Implemented_Expression_ParameterUseConstant(exp,exp.Arguments[0])); + if (exp.Arguments.Count == 1) return ExpressionLambdaToSql(exp.Arguments[0], tsc); + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => $"',{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")},'").ToArray(); + return $"concat({string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs)})"; + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(SqlExtExtensions).GetMethod("StringJoinMySqlGroupConcat"), + Expression.Convert(toListArgs1.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + return newToListSql; + } + break; + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + if (args0Value.Contains("%")) + { + if (exp.Method.Name == "StartsWith") return $"locate({args0Value}, {left}) = 1"; + if (exp.Method.Name == "EndsWith") return $"locate({args0Value}, {left}) = char_length({args0Value})"; + return $"locate({args0Value}, {left}) > 0"; + } + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"concat({args0Value}, '%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"concat('%', {args0Value})")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) LIKE concat('%', {args0Value}, '%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; + return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": + var indexOfFindStr = getExp(exp.Arguments[0]); + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") + { + var locateArgs1 = getExp(exp.Arguments[1]); + if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); + else locateArgs1 += "+1"; + return $"(locate({indexOfFindStr}, {left}, {locateArgs1})-1)"; + } + return $"(locate({indexOfFindStr}, {left})-1)"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; + if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; + } + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + if (exp.Method.Name == "Trim") left = $"trim({getExp(argsTrim01)} from {left})"; + if (exp.Method.Name == "TrimStart") left = $"trim(leading {getExp(argsTrim01)} from {left})"; + if (exp.Method.Name == "TrimEnd") left = $"trim(trailing {getExp(argsTrim01)} from {left})"; + } + } + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"strcmp({left}, {getExp(exp.Arguments[0])})"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": return $"log({getExp(exp.Arguments[0])})"; + case "Log10": return $"log10({getExp(exp.Arguments[0])})"; + case "Pow": return $"pow({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"truncate({getExp(exp.Arguments[0])}, 0)"; + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))"; + case "DaysInMonth": return $"dayofmonth(last_day(concat({getExp(exp.Arguments[0])}, '-', {getExp(exp.Arguments[1])}, '-01')))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; + + case "Parse": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"date_add({left}, interval ({args1}) microsecond)"; + case "AddDays": return $"date_add({left}, interval ({args1}) day)"; + case "AddHours": return $"date_add({left}, interval ({args1}) hour)"; + case "AddMilliseconds": return $"date_add({left}, interval ({args1})*1000 microsecond)"; + case "AddMinutes": return $"date_add({left}, interval ({args1}) minute)"; + case "AddMonths": return $"date_add({left}, interval ({args1}) month)"; + case "AddSeconds": return $"date_add({left}, interval ({args1}) second)"; + case "AddTicks": return $"date_add({left}, interval ({args1})/10 microsecond)"; + case "AddYears": return $"date_add({left}, interval ({args1}) year)"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"timestampdiff(microsecond, {args1}, {left})"; + case "System.TimeSpan": return $"date_sub({left}, interval ({args1}) microsecond)"; + } + break; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"timestampdiff(microsecond,{args1},{left})"; + case "ToString": + if (exp.Arguments.Count == 0) return $"date_format({left},'%Y-%m-%d %H:%i:%s.%f')"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"date_format({left},'%Y-%m-%d %H:%i:%s')"; + case "'yyyy-MM-dd HH:mm'": return $"date_format({left},'%Y-%m-%d %H:%i')"; + case "'yyyy-MM-dd HH'": return $"date_format({left},'%Y-%m-%d %H')"; + case "'yyyy-MM-dd'": return $"date_format({left},'%Y-%m-%d')"; + case "'yyyy-MM'": return $"date_format({left},'%Y-%m')"; + case "'yyyyMMddHHmmss'": return $"date_format({left},'%Y%m%d%H%i%s')"; + case "'yyyyMMddHHmm'": return $"date_format({left},'%Y%m%d%H%i')"; + case "'yyyyMMddHH'": return $"date_format({left},'%Y%m%d%H')"; + case "'yyyyMMdd'": return $"date_format({left},'%Y%m%d')"; + case "'yyyyMM'": return $"date_format({left},'%Y%m')"; + case "'yyyy'": return $"date_format({left},'%Y')"; + case "'HH:mm:ss'": return $"date_format({left},'%H:%i:%s')"; + } + args1 = Regex.Replace(args1, "(yyyy|yy|MM|M|dd|d|HH|H|hh|h|mm|ss|tt)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"%Y"; + case "yy": return $"%y"; + case "MM": return $"%_a1"; + case "M": return $"%c"; + case "dd": return $"%d"; + case "d": return $"%e"; + case "HH": return $"%H"; + case "H": return $"%k"; + case "hh": return $"%h"; + case "h": return $"%l"; + case "mm": return $"%i"; + case "ss": return $"%_a2"; + case "tt": return $"%p"; + } + return m.Groups[0].Value; + }); + var argsFinds = new[] { "%Y", "%y", "%_a1", "%c", "%d", "%e", "%H", "%k", "%h", "%l", "%i", "%_a2", "%p" }; + var argsSpts = Regex.Split(args1, "(m|s|t)"); + for (var a = 0; a < argsSpts.Length; a++) + { + switch (argsSpts[a]) + { + case "m": argsSpts[a] = $"case when substr(date_format({left},'%i'),1,1) = '0' then substr(date_format({left},'%i'),2,1) else date_format({left},'%i') end"; break; + case "s": argsSpts[a] = $"case when substr(date_format({left},'%s'),1,1) = '0' then substr(date_format({left},'%s'),2,1) else date_format({left},'%s') end"; break; + case "t": argsSpts[a] = $"trim(trailing 'M' from date_format({left},'%p'))"; break; + default: + var argsSptsA = argsSpts[a]; + if (argsSptsA.StartsWith("'")) argsSptsA = argsSptsA.Substring(1); + if (argsSptsA.EndsWith("'")) argsSptsA = argsSptsA.Remove(argsSptsA.Length - 1); + argsSpts[a] = argsFinds.Any(m => argsSptsA.Contains(m)) ? $"date_format({left},'{argsSptsA}')" : $"'{argsSptsA}'"; + break; + } + } + if (argsSpts.Length > 0) args1 = $"concat({string.Join(", ", argsSpts.Where(a => a != "''"))})"; + return args1.Replace("%_a1", "%m").Replace("%_a2", "%s"); + } + } + return null; + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60 * 24})"; + case "FromHours": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60})"; + case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})*1000)"; + case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60})"; + case "FromSeconds": return $"(({getExp(exp.Arguments[0])})*1000000)"; + case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10)"; + case "Parse": return $"cast({getExp(exp.Arguments[0])} as signed)"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as signed)"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left}-({args1}))"; + case "ToString": return $"cast({left} as char)"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; + case "ToByte": return $"cast({getExp(exp.Arguments[0])} as unsigned)"; + case "ToChar": return $"substr(cast({getExp(exp.Arguments[0])} as char), 1, 1)"; + case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))"; + case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as decimal(32,16))"; + case "ToInt16": + case "ToInt32": + case "ToInt64": + case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as signed)"; + case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))"; + case "ToString": return $"cast({getExp(exp.Arguments[0])} as char)"; + case "ToUInt16": + case "ToUInt32": + case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as unsigned)"; + } + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlProvider.cs b/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlProvider.cs new file mode 100644 index 00000000..c30b955a --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlProvider.cs @@ -0,0 +1,46 @@ +using FreeSql.Internal.CommonProvider; +using System; +using System.Collections.Concurrent; +using System.Data.Common; +using System.Threading; + +namespace FreeSql.Custom.MySql +{ + + public class CustomMySqlProvider : BaseDbProvider, IFreeSql + { + public override ISelect CreateSelectProvider(object dywhere) => new CustomMySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new CustomMySqlInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new CustomMySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new CustomMySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new CustomMySqlInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); + + public CustomMySqlProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) + { + this.InternalCommonUtils = new CustomMySqlUtils(this); + this.InternalCommonExpression = new CustomMySqlExpression(this.InternalCommonUtils); + + this.Ado = new CustomMySqlAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); + this.Aop = new AopProvider(); + + this.DbFirst = new CustomMySqlDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new CustomMySqlCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + } + + ~CustomMySqlProvider() => this.Dispose(); + int _disposeCounter; + public override void Dispose() + { + if (Interlocked.Increment(ref _disposeCounter) != 1) return; + try + { + (this.Ado as AdoProvider)?.Dispose(); + } + finally + { + FreeSqlCustomAdapterGlobalExtensions._dicCustomAdater.TryRemove(Ado.Identifier, out var tryada); + FreeSqlCustomAdapterGlobalExtensions._dicDbProviderFactory.TryRemove(Ado.Identifier, out var trydbpf); + } + } + } +} diff --git a/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlUtils.cs b/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlUtils.cs new file mode 100644 index 00000000..2cdf0a46 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/MySql/CustomMySqlUtils.cs @@ -0,0 +1,113 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Globalization; + +namespace FreeSql.Custom.MySql +{ + + class CustomMySqlUtils : CommonUtils + { + DbProviderFactory Factory => FreeSqlCustomAdapterGlobalExtensions.GetDbProviderFactory(_orm); + + public CustomMySqlUtils(IFreeSql orm) : base(orm) + { + } + + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + var ret = Factory.CreateParameter(); + ret.ParameterName = QuoteParamterName(parameterName); + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.DbType = (DbType)tp.Value; + ret.Value = value; + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => + { + var ret = Factory.CreateParameter(); + ret.ParameterName = $"@{name}"; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.DbType = (DbType)tp.Value; + ret.Value = value; + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatCustomMySql(args); + public override string QuoteSqlName(params string[] name) + { + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("`") && nametrim.EndsWith("`")) + return nametrim; + return $"`{nametrim.Replace(".", "`.`")}`"; + } + return $"`{string.Join("`.`", name)}`"; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('`').Replace("`.`", ".").Replace(".`", ".")}"; + } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '`', '`', 2); + public override string QuoteParamterName(string name) => $"@{name}"; + public override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"concat({string.Join(", ", objs)})"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} div {right}"; + public override string Now => "now()"; + public override string NowUtc => "utc_timestamp()"; + + public override string QuoteWriteParamterAdapter(Type type, string paramterName) + { + switch (type.FullName) + { + case "MygisPoint": + case "MygisLineString": + case "MygisPolygon": + case "MygisMultiPoint": + case "MygisMultiLineString": + case "MygisMultiPolygon": return $"ST_GeomFromText({paramterName})"; + } + return paramterName; + } + protected override string QuoteReadColumnAdapter(Type type, Type mapType, string columnName) + { + switch (mapType.FullName) + { + case "MygisPoint": + case "MygisLineString": + case "MygisPolygon": + case "MygisMultiPoint": + case "MygisMultiLineString": + case "MygisMultiPolygon": return $"ST_AsText({columnName})"; + } + return columnName; + } + + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) + { + if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); + if (type == typeof(byte[])) return $"0x{CommonUtils.BytesSqlRaw(value as byte[])}"; + if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) + { + var ts = (TimeSpan)value; + value = $"{Math.Floor(ts.TotalHours)}:{ts.Minutes}:{ts.Seconds}"; + } + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleDelete.cs b/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleDelete.cs new file mode 100644 index 00000000..cb077459 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleDelete.cs @@ -0,0 +1,26 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Custom.Oracle +{ + + class CustomOracleDelete : Internal.CommonProvider.DeleteProvider + { + public CustomOracleDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() => throw new NotImplementedException($"FreeSql.Odbc.Oracle {CoreStrings.S_Not_Implemented_Feature}"); + +#if net40 +#else + public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException($"FreeSql.Odbc.Oracle {CoreStrings.S_Not_Implemented_Feature}"); +#endif + } +} diff --git a/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleInsert.cs b/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleInsert.cs new file mode 100644 index 00000000..bca3820e --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleInsert.cs @@ -0,0 +1,224 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Custom.Oracle +{ + + class CustomOracleInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public CustomOracleInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + + public override string ToSql() + { + if (_source == null || _source.Any() == false) return null; + var sb = new StringBuilder(); + sb.Append("INSERT "); + if (_source.Count > 1) sb.Append("ALL"); + + _identCol = null; + var sbtb = new StringBuilder(); + sbtb.Append("INTO "); + sbtb.Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append("("); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (col.Attribute.IsIdentity) _identCol = col; + if (col.Attribute.IsIdentity && _insertIdentity == false && string.IsNullOrEmpty(col.DbInsertValue)) continue; + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; + + if (colidx > 0) sbtb.Append(", "); + sbtb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)); + ++colidx; + } + sbtb.Append(") "); + + _params = _noneParameter ? new DbParameter[0] : new DbParameter[colidx * _source.Count]; + var specialParams = new List(); + var didx = 0; + foreach (var d in _source) + { + if (_source.Count > 1) sb.Append("\r\n"); + sb.Append(sbtb); + sb.Append("VALUES"); + sb.Append("("); + var colidx2 = 0; + foreach (var col in _table.Columns.Values) + { + if (col.Attribute.IsIdentity && _insertIdentity == false && string.IsNullOrEmpty(col.DbInsertValue)) continue; + if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue; + + if (colidx2 > 0) sb.Append(", "); + if (string.IsNullOrEmpty(col.DbInsertValue) == false) + sb.Append(col.DbInsertValue); + else + { + object val = col.GetDbValue(d); + if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384 + + var colsql = _noneParameter ? _commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col, col.Attribute.MapType, val) : + _commonUtils.QuoteWriteParamterAdapter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}")); + sb.Append(_commonUtils.RewriteColumn(col, colsql)); + if (_noneParameter == false) + _params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col, col.Attribute.MapType, val); + } + ++colidx2; + } + sb.Append(")"); + ++didx; + } + if (_noneParameter && specialParams.Any()) _params = specialParams.ToArray(); + if (_source.Count > 1) sb.Append("\r\n SELECT 1 FROM DUAL"); + return sb.ToString(); + } + + ColumnInfo _identCol; + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + if (_identCol == null || _source.Count > 1) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return 0; + } + var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); + var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol, _identCol.Attribute.MapType, 0); + identParam.Direction = ParameterDirection.Output; + sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; + var dbParms = _params.Concat(new[] { identParam }).ToArray(); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + long.TryParse(string.Concat(identParam.Value), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var ret = _source.ToList(); + this.RawExecuteAffrows(); + return ret; + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + if (_identCol == null || _source.Count > 1) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return 0; + } + var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); + var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol, _identCol.Attribute.MapType, 0); + identParam.Direction = ParameterDirection.Output; + sql = $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}"; + var dbParms = _params.Concat(new[] { identParam }).ToArray(); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + long.TryParse(string.Concat(identParam.Value), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var ret = _source.ToList(); + await this.RawExecuteAffrowsAsync(cancellationToken); + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleInsertOrUpdate.cs b/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleInsertOrUpdate.cs new file mode 100644 index 00000000..e68b6d57 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleInsertOrUpdate.cs @@ -0,0 +1,74 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Text; + +namespace FreeSql.Custom.Oracle +{ + + class CustomOracleInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public CustomOracleInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + var dbParams = new List(); + if (_sourceSql != null) return getMergeSql(null); + if (_source?.Any() != true) return null; + + var sqls = new string[2]; + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = string.Join("\r\n\r\n;\r\n\r\n", ds.Item1.Select(a => getMergeSql(a))); + if (ds.Item2.Any()) sqls[1] = string.Join("\r\n\r\n;\r\n\r\n", ds.Item2.Select(a => getInsertSql(a))); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); + + string getMergeSql(List data) + { + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); + + var sb = new StringBuilder().Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); + WriteSourceSelectUnionAll(data, sb, dbParams); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); + + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + if (_doNothing == false && cols.Any()) + sb.Append("WHEN MATCHED THEN \r\n") + .Append(" update set ").Append(string.Join(", ", cols.Select(a => + a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}" + ))).Append(" \r\n"); + + cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); + if (cols.Any()) + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(")"); + + return sb.ToString(); + } + string getInsertSql(List data) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + insert._table = _table; + var sql = insert.ToSql(); + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleSelect.cs b/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleSelect.cs new file mode 100644 index 00000000..0b51424f --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleSelect.cs @@ -0,0 +1,232 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Custom.Oracle +{ + + class CustomOracleSelect : FreeSql.Internal.CommonProvider.Select1Provider + { + + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereGlobalFilter.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); + + var sb = new StringBuilder(); + var sbunion = new StringBuilder(); + var sbnav = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); + var tbUnion = tbUnions[tbUnionsIdx]; + + sbunion.Append(_select); + if (_distinct) sbunion.Append("DISTINCT "); + sbunion.Append(field); + if (string.IsNullOrEmpty(_orderby) && _skip > 0) sbunion.Append(", ROWNUM AS \"__rownum__\""); + sbunion.Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sbunion.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sbunion.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sbunion.Append(" ON 1 = 1"); + else + { + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sbunion.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sbunion.Append(tbsfrom[b].Cascade); + else sbunion.Append(" AND ").Append(tbsfrom[b].Cascade); + } + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); + } + if (a < tbsfrom.Length - 1) sbunion.Append(", "); + } + foreach (var tb in tbsjoin) + { + switch (tb.Type) + { + case SelectTableInfoType.Parent: + case SelectTableInfoType.RawJoin: + continue; + case SelectTableInfoType.LeftJoin: + sbunion.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sbunion.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sbunion.Append(" \r\nRIGHT JOIN "); + break; + } + sbunion.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sbunion.Append(" AND ").Append(tb.Cascade); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sbunion.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND ").Append(_tables[0].Cascade); + + if (string.IsNullOrEmpty(_orderby) && (_skip > 0 || _limit > 0)) + sbnav.Append(" AND ROWNUM < ").Append(_skip + _limit + 1); + if (sbnav.Length > 0) + sbunion.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + if (string.IsNullOrEmpty(_groupby) == false) + { + sbunion.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sbunion.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sbunion.Append(_orderby); + + if (string.IsNullOrEmpty(_orderby)) + { + if (_skip > 0) + sbunion.Insert(0, $"{_select}t.* FROM (").Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); + } + else + { + if (_skip > 0 && _limit > 0) sbunion.Insert(0, $"{_select}t.* FROM (SELECT rt.*, ROWNUM AS \"__rownum__\" FROM (").Append(") rt WHERE ROWNUM < ").Append(_skip + _limit + 1).Append(") t WHERE t.\"__rownum__\" > ").Append(_skip); + else if (_skip > 0) sbunion.Insert(0, $"{_select}t.* FROM (").Append(") t WHERE ROWNUM > ").Append(_skip); + else if (_limit > 0) sbunion.Insert(0, $"{_select}t.* FROM (").Append(") t WHERE ROWNUM < ").Append(_limit + 1); + } + + if (tbUnionsGt0) sbunion.Insert(0, $"{_select}* from (").Append(") ftb"); + sb.Append(sbunion); + sbnav.Clear(); + sbunion.Clear(); + } + var sql = sb.Append(_tosqlAppendContent).ToString(); + + var aliasGreater30 = 0; + foreach (var tb in _tables) + if (tb.Alias.Length > 30) sql = sql.Replace(tb.Alias, $"than30_{aliasGreater30++}"); + + return sql; + } + + public CustomOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); CustomOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); CustomOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); CustomOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); CustomOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); CustomOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); CustomOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); CustomOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); CustomOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); CustomOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); CustomOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); CustomOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); CustomOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); CustomOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); CustomOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcOracleSelect(_orm, _commonUtils, _commonExpression, null); CustomOracleSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcOracleSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public OdbcOracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomOracleSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } +} diff --git a/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleUpdate.cs b/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleUpdate.cs new file mode 100644 index 00000000..4b692249 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleUpdate.cs @@ -0,0 +1,74 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Custom.Oracle +{ + + class CustomOracleUpdate : Internal.CommonProvider.UpdateProvider + { + + public CustomOracleUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999); + + protected override List RawExecuteUpdated() => throw new NotImplementedException($"FreeSql.Odbc.Oracle {CoreStrings.S_Not_Implemented_Feature}"); + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (primarys.Length == 1) + { + var pk = primarys.First(); + caseWhen.Append(_commonUtils.RereadColumn(pk, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in primarys) + { + if (pkidx > 0) caseWhen.Append(" || '+' || "); + caseWhen.Append(_commonUtils.RereadColumn(pk, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (primarys.Length == 1) + { + if (primarys[0].Attribute.DbType.Contains("NVARCHAR2")) + sb.Append("N"); + sb.Append(_commonUtils.FormatSql("{0}", primarys[0].GetDbValue(d))); + return; + } + sb.Append("("); + var pkidx = 0; + foreach (var pk in primarys) + { + if (pkidx > 0) sb.Append(" || '+' || "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))); + ++pkidx; + } + sb.Append(")"); + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 200, _batchParameterLimit > 0 ? _batchParameterLimit : 999, cancellationToken); + + protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException($"FreeSql.Odbc.Oracle {CoreStrings.S_Not_Implemented_Feature}"); +#endif + } +} diff --git a/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleAdo/CustomOracleAdo.cs b/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleAdo/CustomOracleAdo.cs new file mode 100644 index 00000000..5a0e3a56 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleAdo/CustomOracleAdo.cs @@ -0,0 +1,81 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using FreeSql.Internal.ObjectPool; +using System; +using System.Collections; +using System.Data.Common; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; + +namespace FreeSql.Custom.Oracle +{ + class CustomOracleAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + DbProviderFactory Factory => FreeSqlCustomAdapterGlobalExtensions.GetDbProviderFactory(_util._orm); + + public CustomOracleAdo() : base(DataType.OdbcOracle, null, null) { } + public CustomOracleAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcOracle, masterConnectionString, slaveConnectionStrings) + { + base._util = util; + if (connectionFactory != null) + { + var pool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.SqlServer, connectionFactory); + MasterPool = pool; + using (var conn = pool.Get()) + UserId = CustomOracleAdo.GetUserId(conn.Value.ConnectionString); + return; + } + throw new Exception(CoreStrings.S_CustomAdapter_OnlySuppport_UseConnectionFactory); + } + + internal string UserId { get; set; } + public static string GetUserId(string connectionString) + { + var userIdMatch = Regex.Match(connectionString, @"(User\s+Id|Uid)\s*=\s*([^;]+)", RegexOptions.IgnoreCase); + if (userIdMatch.Success == false) throw new Exception(@"从 ConnectionString 中无法匹配 (User\s+Id|Uid)\s*=\s*([^;]+)"); + return userIdMatch.Groups[2].Value.Trim().ToUpper(); + } + + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) + param = Utils.GetDataReaderValue(mapType, param); + + if (param is byte[]) + return $"hextoraw('{CommonUtils.BytesSqlRaw(param as byte[])}')"; + else if (param is bool || param is bool?) + return (bool)param ? 1 : 0; + else if (param is string) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return string.Concat("to_timestamp('", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "','YYYY-MM-DD HH24:MI:SS.FF6')"); + else if (param is TimeSpan || param is TimeSpan?) + return $"numtodsinterval({((TimeSpan)param).Ticks * 1.0 / 10000000},'second')"; + else if (param is IEnumerable) + return AddslashesIEnumerable(param, mapType, mapColumn); + + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + //if (param is string) return string.Concat('N', nparms[a]); + } + + public override DbCommand CreateCommand() + { + return Factory.CreateCommand(); + } + + public override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) + { + pool.Return(conn); + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} diff --git a/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleCodeFirst.cs b/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleCodeFirst.cs new file mode 100644 index 00000000..3f7b4f6d --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleCodeFirst.cs @@ -0,0 +1,503 @@ +using FreeSql.DataAnnotations; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Custom.Oracle +{ + + class CustomOracleCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; } + public CustomOracleCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + + static object _dicCsToDbLock = new object(); + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(bool).FullName, CsToDb.New(DbType.Boolean, "number","number(1) NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(DbType.Boolean, "number","number(1) NULL", null, true, null) }, + + { typeof(sbyte).FullName, CsToDb.New(DbType.SByte, "number", "number(4) NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(DbType.SByte, "number", "number(4) NULL", false, true, null) }, + { typeof(short).FullName, CsToDb.New(DbType.Int16, "number","number(6) NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(DbType.Int16, "number", "number(6) NULL", false, true, null) }, + { typeof(int).FullName, CsToDb.New(DbType.Int32, "number", "number(11) NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(DbType.Int32, "number", "number(11) NULL", false, true, null) }, + { typeof(long).FullName, CsToDb.New(DbType.Int64, "number","number(21) NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(DbType.Int64, "number","number(21) NULL", false, true, null) }, + + { typeof(byte).FullName, CsToDb.New(DbType.Byte, "number","number(3) NOT NULL", true, false, 0) },{ typeof(byte?).FullName, CsToDb.New(DbType.Byte, "number","number(3) NULL", true, true, null) }, + { typeof(ushort).FullName, CsToDb.New(DbType.UInt16, "number","number(5) NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(DbType.UInt16, "number", "number(5) NULL", true, true, null) }, + { typeof(uint).FullName, CsToDb.New(DbType.UInt32, "number", "number(10) NOT NULL", true, false, 0) },{ typeof(uint?).FullName, CsToDb.New(DbType.UInt32, "number", "number(10) NULL", true, true, null) }, + { typeof(ulong).FullName, CsToDb.New(DbType.UInt64, "number", "number(20) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(DbType.UInt64, "number", "number(20) NULL", true, true, null) }, + + { typeof(double).FullName, CsToDb.New(DbType.Double, "float", "float(126) NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(DbType.Double, "float", "float(126) NULL", false, true, null) }, + { typeof(float).FullName, CsToDb.New(DbType.Single, "float","float(63) NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(DbType.Single, "float","float(63) NULL", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(DbType.Decimal, "number", "number(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(DbType.Decimal, "number", "number(10,2) NULL", false, true, null) }, + + { typeof(TimeSpan).FullName, CsToDb.New(DbType.Time, "interval day to second","interval day(2) to second(6) NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(DbType.Time, "interval day to second", "interval day(2) to second(6) NULL",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(DbType.DateTime, "timestamp", "timestamp(6) NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(DbType.DateTime, "timestamp", "timestamp(6) NULL", false, true, null) }, + { typeof(DateTimeOffset).FullName, CsToDb.New(DbType.DateTimeOffset, "timestamp with local time zone", "timestamp(6) with local time zone NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTimeOffset?).FullName, CsToDb.New(DbType.DateTimeOffset, "timestamp with local time zone", "timestamp(6) with local time zone NULL", false, true, null) }, + + { typeof(byte[]).FullName, CsToDb.New(DbType.Binary, "blob", "blob NULL", false, null, new byte[0]) }, + { typeof(string).FullName, CsToDb.New(DbType.String, "nvarchar2", "nvarchar2(255) NULL", false, null, "") }, + { typeof(char).FullName, CsToDb.New(DbType.AnsiString, "char", "char(1 CHAR) NULL", false, null, '\0') }, + + { typeof(Guid).FullName, CsToDb.New(DbType.Guid, "char", "char(36 CHAR) NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(DbType.Guid, "char", "char(36 CHAR) NULL", false, true, null) }, + }; + + public override DbInfoResult GetDbInfo(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + CsToDb.New(DbType.Int32, "number", $"number(16){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(DbType.Int64, "number", $"number(32){(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue); + } + return null; + } + + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) + { + var userId = (_orm.Ado as CustomOracleAdo)?.UserId; + if (string.IsNullOrEmpty(userId)) + using (var conn = _orm.Ado.MasterPool.Get()) + { + userId = CustomOracleAdo.GetUserId(conn.Value.ConnectionString); + } + var seqcols = new List>(); //序列:列,表,自增 + var seqnameDel = new List(); //要删除的序列+触发器 + + var sb = new StringBuilder(); + var sbDeclare = new StringBuilder(); + foreach (var obj in objects) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception(CoreStrings.S_Type_IsNot_Migrable(obj.entityType.FullName)); + if (tb.Columns.Any() == false) throw new Exception(CoreStrings.S_Type_IsNot_Migrable_0Attributes(obj.entityType.FullName)); + var tbname = _commonUtils.SplitTableName(tb.DbName); + if (tbname?.Length == 1) tbname = new[] { userId, tbname[0] }; + + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { userId, tboldname[0] }; + var primaryKeyName = (obj.entityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute), false)?.FirstOrDefault() as OraclePrimaryKeyNameAttribute)?.Name; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); + if (tbtmpname?.Length == 1) tbtmpname = new[] { userId, tbtmpname[0] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) + { + tbname = tbtmpname; + tboldname = null; + primaryKeyName = null; + } + } + //codefirst 不支持表名中带 . + + if (string.Compare(tbname[0], userId) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from sys.dba_users where username={0}", tbname[0])) == null) //创建数据库 + throw new NotImplementedException(CoreStrings.S_Oracle_NotSupport_TablespaceSchemas(tbname[0])); + + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_comments where owner={0} and table_name={1}", tbname)) == null) + { //表不存在 + if (tboldname != null) + { + if (_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_comments where owner={0} and table_name={1}", tboldname)) == null) + //模式或表不存在 + tboldname = null; + } + if (tboldname == null) + { + //创建表 + var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + sb.Append("execute immediate 'CREATE TABLE ").Append(createTableName).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk1"; + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) \r\nLOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("execute immediate 'CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(")';\r\n"); + } + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); + } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + continue; + } + //如果新表,旧表在一个模式下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0) + sbalter.Append("execute immediate '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 sql = _commonUtils.FormatSql($@" +select +a.column_name, +a.data_type, +a.data_length, +a.data_precision, +a.data_scale, +a.char_used, +case when a.nullable = 'N' then 0 else 1 end, +nvl((select 1 from user_sequences where upper(sequence_name)=upper('{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name) and rownum < 2), 0), +nvl((select 1 from user_triggers where upper(trigger_name)=upper('{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI') and rownum < 2), 0), +b.comments +from all_tab_columns a +left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name +where a.owner={{0}} and a.table_name={{1}} and a.column_id is not null", tboldname ?? tbname); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => + { + var sqlType = GetOracleSqlTypeFullName(a); + return new + { + column = string.Concat(a[0]), + sqlType, + is_nullable = string.Concat(a[6]) == "1", + is_identity = string.Concat(a[7]) == "1" && string.Concat(a[8]) == "1", + comment = string.Concat(a[9]) + }; + }, StringComparer.CurrentCultureIgnoreCase); + + if (istmpatler == false) + { + foreach (var tbcol in tb.ColumnsByPosition) + { + var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"NOT\s+NULL", "NULL"); + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { + istmpatler = true; + if (tbcol.Attribute.DbType.StartsWith("varchar", StringComparison.CurrentCultureIgnoreCase) && tbstructcol.sqlType.StartsWith("varchar2", StringComparison.CurrentCultureIgnoreCase) + && Regex.Match(tbcol.Attribute.DbType, @"\(\d+").Groups[0].Value == Regex.Match(tbstructcol.sqlType, @"\(\d+").Groups[0].Value) + istmpatler = false; + if (istmpatler) break; + } + //sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + { + if (tbcol.Attribute.IsNullable == false) + sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue.Replace("'", "''")).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL';\r\n"); + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "" : "NOT").Append(" NULL';\r\n"); + } + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + { + if (tbstructcol.is_identity) + seqnameDel.Add(Utils.GetCsName($"{tbname[1]}_seq_{tbstructcol.column}")); + //修改列名 + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append("';\r\n"); + if (tbcol.Attribute.IsIdentity) + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + } + else if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (isCommentChanged) + sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); + continue; + } + //添加列 + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD (").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); + if (tbcol.Attribute.IsNullable == false) + { + sbalter.Append("execute immediate 'UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue.Replace("'", "''")).Append("';\r\n"); + sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" NOT NULL';\r\n"); + } + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment ?? "").Replace("'", "''")).Append("';\r\n"); + } + } + if (istmpatler == false) + { + CreateOracleFunction(_orm); + var dsuksql = _commonUtils.FormatSql(@" +select +nvl(freesql_long_2_varchar(a.index_name, c.table_name, c.column_position), c.column_name), +a.index_name, +case when c.descend = 'DESC' then 1 else 0 end, +case when a.uniqueness = 'UNIQUE' then 1 else 0 end +from all_indexes a, +all_ind_columns c +where a.index_name = c.index_name +and a.table_owner = c.table_owner +and a.table_name = c.table_name +and a.owner in ({0}) and a.table_name in ({1}) +and not exists(select 1 from all_constraints where constraint_name = a.index_name and constraint_type = 'P')", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]).Trim('"'), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }).ToArray(); + foreach (var uk in tb.Indexes) + { + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var ukname = ReplaceIndexName(uk.Name, tbname[1]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) + { + if (dsukfind1.Any()) sbalter.Append("execute immediate 'DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append("';\r\n"); + sbalter.Append("execute immediate 'CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } + sbalter.Remove(sbalter.Length - 2, 2).Append(")';\r\n"); + } + } + } + if (istmpatler == false) + { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select comments from all_tab_comments where owner = {0} and table_name = {1} and table_type = 'TABLE'", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + + sb.Append(sbalter); + continue; + } + var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select constraint_name from user_constraints where owner={0} and table_name={1} and constraint_type='P'", tbname))?.ToString(); + if (string.IsNullOrEmpty(oldpk) == false) + sb.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(oldpk)).Append("';\r\n"); + + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + var tablename = tboldname == null ? _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}") : _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"); + var tmptablename = _commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}"); + //创建临时表 + sb.Append("execute immediate 'CREATE TABLE ").Append(tmptablename).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); + if (tbcol.Attribute.IsIdentity == true) seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); + } + if (tb.Primarys.Any()) + { + var pkname = primaryKeyName ?? $"{tbname[0]}_{tbname[1]}_pk2"; + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) LOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); + } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + + sb.Append("execute immediate 'INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.ColumnsByPosition) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.ColumnsByPosition) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { + var dbtypeNoneNotNull = Regex.Replace(tbcol.Attribute.DbType, @"(NOT\s+)?NULL", ""); + insertvalue = $"cast({insertvalue} as {dbtypeNoneNotNull})"; + } + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"nvl({insertvalue},{tbcol.DbDefaultValue})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = tbcol.DbDefaultValue; + sb.Append(insertvalue.Replace("'", "''")).Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(" FROM ").Append(tablename).Append("';\r\n"); + sb.Append("execute immediate 'DROP TABLE ").Append(tablename).Append("';\r\n"); + sb.Append("execute immediate 'ALTER TABLE ").Append(tmptablename).Append(" RENAME TO ").Append(_commonUtils.QuoteSqlName($"{tbname[1]}")).Append("';\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("execute immediate 'CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(")';\r\n"); + } + } + Dictionary dicDeclare = new Dictionary(); + Action dropSequence = seqname => + { + if (dicDeclare.ContainsKey(seqname) == false) + { + sbDeclare.Append("\r\nIS").Append(seqname).Append(" NUMBER; \r\n"); + dicDeclare.Add(seqname, true); + } + sb.Append("IS").Append(seqname).Append(" := 0; \r\n") + .Append(" select count(1) into IS").Append(seqname).Append(_commonUtils.FormatSql(" from user_sequences where sequence_name={0}; \r\n", seqname)) + .Append("if IS").Append(seqname).Append(" > 0 then \r\n") + .Append(" execute immediate 'DROP SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append("';\r\n") + .Append("end if; \r\n"); + }; + Action dropTrigger = tiggerName => + { + if (dicDeclare.ContainsKey(tiggerName) == false) + { + sbDeclare.Append("\r\nIS").Append(tiggerName).Append(" NUMBER; \r\n"); + dicDeclare.Add(tiggerName, true); + } + sb.Append("IS").Append(tiggerName).Append(" := 0; \r\n") + .Append(" select count(1) into IS").Append(tiggerName).Append(_commonUtils.FormatSql(" from user_triggers where trigger_name={0}; \r\n", tiggerName)) + .Append("if IS").Append(tiggerName).Append(" > 0 then \r\n") + .Append(" execute immediate 'DROP TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)).Append("';\r\n") + .Append("end if; \r\n"); + }; + foreach (var seqname in seqnameDel) + { + dropSequence(seqname); + dropTrigger(seqname + "TI"); + } + foreach (var seqcol in seqcols) + { + var tbname = seqcol.Item2; + var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}").ToUpper(); + var tiggerName = seqname + "TI"; + var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); + dropSequence(seqname); + if (seqcol.Item3) + { + var startWith = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from all_tab_columns where owner={0} and table_name={1} and column_name={2}", tbname[0], tbname[1], seqcol.Item1.Attribute.Name)) == null ? 1 : + _orm.Ado.ExecuteScalar(CommandType.Text, $" select nvl(max({colname2})+1,1) from {tbname2}"); + sb.Append("execute immediate 'CREATE SEQUENCE ").Append(_commonUtils.QuoteSqlName(seqname)).Append(" start with ").Append(startWith).Append("';\r\n"); + sb.Append("execute immediate 'CREATE OR REPLACE TRIGGER ").Append(_commonUtils.QuoteSqlName(tiggerName)) + .Append(" \r\nbefore insert on ").Append(tbname2) + .Append(" \r\nfor each row \r\nbegin\r\nselect ").Append(_commonUtils.QuoteSqlName(seqname)) + .Append(".nextval into :new.").Append(colname2).Append(" from dual;\r\nend;';\r\n"); + } + else + dropTrigger(tiggerName); + } + if (sbDeclare.Length > 0) sbDeclare.Insert(0, "declare "); + return sb.Length == 0 ? null : sb.Insert(0, "BEGIN \r\n").Insert(0, sbDeclare.ToString()).Append("END;").ToString(); + } + + internal static string GetOracleSqlTypeFullName(object[] row) + { + var a = row; + var sqlType = string.Concat(a[1]).ToUpper(); + var data_length = long.Parse(string.Concat(a[2])); + long.TryParse(string.Concat(a[3]), out var data_precision); + long.TryParse(string.Concat(a[4]), out var data_scale); + var char_used = string.Concat(a[5]); + if (Regex.IsMatch(sqlType, @"INTERVAL DAY\(\d+\) TO SECOND\(\d+\)", RegexOptions.IgnoreCase)) + { + } + else if (Regex.IsMatch(sqlType, @"INTERVAL YEAR\(\d+\) TO MONTH", RegexOptions.IgnoreCase)) + { + } + else if (sqlType.StartsWith("TIMESTAMP", StringComparison.CurrentCultureIgnoreCase)) + { + } + else if (sqlType.StartsWith("BLOB")) + { + } + else if (sqlType.StartsWith("CLOB")) + { + } + else if (sqlType.StartsWith("NCLOB")) + { + } + else if (char_used.ToLower() == "c") + sqlType += sqlType.StartsWith("N") ? $"({data_length / 2})" : $"({data_length / 4} CHAR)"; + else if (char_used.ToLower() == "b") + sqlType += $"({data_length} BYTE)"; + else if (sqlType.ToLower() == "float") + sqlType += $"({data_precision})"; + else if (data_precision > 0 && data_scale > 0) + sqlType += $"({data_precision},{data_scale})"; + else if (data_precision > 0) + sqlType += $"({data_precision})"; + else + sqlType += $"({data_length})"; + return sqlType; + } + + internal static void CreateOracleFunction(IFreeSql fsql) + { + fsql.Ado.ExecuteNonQuery(CommandType.Text, @" +CREATE OR REPLACE FUNCTION freesql_long_2_varchar ( + p_index_name IN user_ind_expressions.index_name%TYPE, + p_table_name IN user_ind_expressions.table_name%TYPE, + p_COLUMN_POSITION IN user_ind_expressions.table_name%TYPE) + RETURN VARCHAR2 +AS + l_COLUMN_EXPRESSION LONG; +BEGIN + SELECT COLUMN_EXPRESSION + INTO l_COLUMN_EXPRESSION + FROM user_ind_expressions + WHERE index_name = p_index_name + AND table_name = p_table_name + AND COLUMN_POSITION = p_COLUMN_POSITION; + + RETURN SUBSTR (l_COLUMN_EXPRESSION, 1, 4000); +END;"); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleDbFirst.cs b/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleDbFirst.cs new file mode 100644 index 00000000..e3a9efc6 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleDbFirst.cs @@ -0,0 +1,584 @@ +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Custom.Oracle +{ + class CustomOracleDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public CustomOracleDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column); + DbType GetSqlDbType(DbColumnInfo column) + { + var dbfull = column.DbTypeTextFull?.ToLower(); + switch (dbfull) + { + case "number(1)": return DbType.Boolean; + + case "number(4)": return DbType.SByte; + case "number(6)": return DbType.Int16; + case "number(11)": return DbType.Int32; + case "number(21)": return DbType.Int64; + + case "number(3)": return DbType.Byte; + case "number(5)": return DbType.UInt16; + case "number(10)": return DbType.UInt32; + case "number(20)": return DbType.UInt64; + + case "float(126)": return DbType.Double; + case "float(63)": return DbType.Single; + case "number(10,2)": return DbType.Decimal; + + case "interval day(2) to second(6)": return DbType.Time; + case "timestamp(6)": return DbType.DateTime; + case "timestamp(6) with local time zone": return DbType.DateTime; + + case "blob": return DbType.Binary; + case "nvarchar2(255)": return DbType.String; + + case "char(36 char)": return DbType.Guid; + } + switch (column.DbTypeText?.ToLower()) + { + case "number": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["number(10,2)"]); + return DbType.Decimal; + case "float": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(126)"]); + return DbType.Double; + case "interval day to second": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["interval day(2) to second(6)"]); + return DbType.Time; + case "date": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["date"]); + return DbType.DateTime; + case "timestamp": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["timestamp(6)"]); + return DbType.DateTime; + case "timestamp with local time zone": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["timestamp(6) with local time zone"]); + return DbType.DateTime; + case "blob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return DbType.Binary; + case "nvarchar2": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return DbType.String; + case "varchar2": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return DbType.String; + case "char": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return DbType.String; + case "nchar": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return DbType.String; + case "clob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return DbType.String; + case "nclob": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return DbType.String; + case "raw": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return DbType.Binary; + case "long raw": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["blob"]); + return DbType.Binary; + case "binary_float": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(63)"]); + return DbType.Single; + case "binary_double": + _dicDbToCs.TryAdd(dbfull, _dicDbToCs["float(126)"]); + return DbType.Double; + case "rowid": + default: + if (dbfull != null) _dicDbToCs.TryAdd(dbfull, _dicDbToCs["nvarchar2(255)"]); + return DbType.String; + } + throw new NotImplementedException(CoreStrings.S_TypeMappingNotImplemented(column.DbTypeTextFull)); + } + + static ConcurrentDictionary _dicDbToCs = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + static CustomOracleDbFirst() + { + var defaultDbToCs = new Dictionary() { + { "number(1)", new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + + { "number(4)", new DbToCs("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetInt16") }, + { "number(6)", new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { "number(11)", new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { "number(21)", new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + + { "number(3)", new DbToCs("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { "number(5)", new DbToCs("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") }, + { "number(10)", new DbToCs("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") }, + { "number(20)", new DbToCs("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetDecimal") }, + + { "float(126)", new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { "float(63)", new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { "number(10,2)", new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + + { "interval day(2) to second(6)", new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { "date", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "timestamp(6)", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + { "timestamp(6) with local time zone", new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetValue") }, + + { "blob", new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + { "nvarchar2(255)", new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { "char(36 char)", new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, + }; + foreach (var kv in defaultDbToCs) + _dicDbToCs.TryAdd(kv.Key, kv.Value); + } + + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbTypeTextFull, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + var sql = @" select username from all_users"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); + } + + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) + { + var userId = (_orm.Ado as CustomOracleAdo)?.UserId; + if (string.IsNullOrEmpty(userId)) + using (var conn = _orm.Ado.MasterPool.Get()) + { + userId = CustomOracleAdo.GetUserId(conn.Value.ConnectionString); + } + tbname = new[] { userId, tbname[0] }; + } + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $" select 1 from all_tab_comments where {(ignoreCase ? "lower(owner)" : "owner")}={_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(table_name)" : "table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) + { + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + string[] tbname = null; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) + { + var userUsers = _orm.Ado.ExecuteScalar(" select username from user_users")?.ToString(); + if (string.IsNullOrEmpty(userUsers)) return loc1; + tbname = new[] { userUsers, tbname[0] }; + } + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + database = new[] { tbname[0] }; + } + else if (database == null || database.Any() == false) + { + var userUsers = _orm.Ado.ExecuteScalar(" select username from user_users")?.ToString(); + if (string.IsNullOrEmpty(userUsers)) return loc1; + database = new[] { userUsers }; + } + + var databaseIn = string.Join(",", database.Select(a => _commonUtils.FormatSql("{0}", a))); + var sql = $@" +select +a.owner || '.' || a.table_name AS tbname, +a.owner, +a.table_name, +b.comments, +'TABLE' AS tp +from all_tables a +left join all_tab_comments b on b.owner = a.owner and b.table_name = a.table_name and b.table_type = 'TABLE' +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.table_name)" : "a.table_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")} + +UNION ALL + +select +a.owner || '.' || a.view_name, +a.owner, +a.view_name, +b.comments, +'VIEW' AS tp +from all_views a +left join all_tab_comments b on b.owner = a.owner and b.table_name = a.view_name and b.table_type = 'VIEW' +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}){(tbname == null ? "" : $" and {(ignoreCase ? "lower(a.view_name)" : "a.view_name")}={_commonUtils.FormatSql("{0}", tbname[1])}")} +"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); + foreach (var row in ds) + { + var table_id = string.Concat(row[0]); + var schema = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + var type = string.Concat(row[4]) == "VIEW" ? DbTableType.VIEW : DbTableType.TABLE; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + schema = ""; + } + loc2.Add(table_id, new DbTableInfo { Id = table_id, Schema = schema, Name = table, Comment = comment, Type = type }); + loc3.Add(table_id, new Dictionary()); + switch (type) + { + case DbTableType.TABLE: + case DbTableType.VIEW: + loc6_1000.Add(table.Replace("'", "''")); + if (loc6_1000.Count >= 999) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } + break; + case DbTableType.StoreProcedure: + loc66_1000.Add(table.Replace("'", "''")); + if (loc66_1000.Count >= 999) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } + break; + } + } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + + if (loc6.Count == 0) return loc1; + var loc8 = new StringBuilder().Append("("); + for (var loc8idx = 0; loc8idx < loc6.Count; loc8idx++) + { + if (loc8idx > 0) loc8.Append(" OR "); + loc8.Append("a.table_name in ("); + for (var loc8idx2 = 0; loc8idx2 < loc6[loc8idx].Length; loc8idx2++) + { + if (loc8idx2 > 0) loc8.Append(","); + loc8.Append($"'{loc6[loc8idx][loc8idx2]}'"); + } + loc8.Append(")"); + } + loc8.Append(")"); + + _orm.Ado.ExecuteNonQuery(CommandType.Text, @" +CREATE OR REPLACE FUNCTION FREESQL_LONG_TO_CHAR_DEFAULT +( + TABLE_NAME VARCHAR, + COLUMN VARCHAR2 +) + RETURN VARCHAR AS + TEXT_C1 VARCHAR2(32767); + SQL_CUR VARCHAR2(2000); +BEGIN + DBMS_OUTPUT.ENABLE(BUFFER_SIZE => NULL); + SQL_CUR := 'SELECT T.DATA_DEFAULT FROM USER_TAB_COLUMNS T WHERE T.TABLE_NAME = '''||TABLE_NAME||''' AND T.COLUMN_NAME='''||COLUMN||''''; + DBMS_OUTPUT.PUT_LINE(SQL_CUR); + EXECUTE IMMEDIATE SQL_CUR + INTO TEXT_C1; + TEXT_C1 := SUBSTR(TEXT_C1, 1, 4000); + RETURN TEXT_C1; +END;"); + + sql = $@" +select +a.owner || '.' || a.table_name, +a.column_name, +a.data_type, +a.data_length, +a.data_precision, +a.data_scale, +a.char_used, +case when a.nullable = 'N' then 0 else 1 end, +nvl((select 1 from user_sequences where upper(sequence_name)=upper(a.table_name||'_seq_'||a.column_name) and rownum < 2), 0), +to_char(b.comments), +nvl(FREESQL_LONG_TO_CHAR_DEFAULT(a.table_name, a.column_name),'') +from all_tab_cols a +left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name +where {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} and a.column_id is not null +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var ds2 = new List(); + foreach (var row in ds) + { + var ds2item = new object[9]; + ds2item[0] = row[0]; + ds2item[1] = row[1]; + ds2item[2] = Regex.Replace(string.Concat(row[2]), @"\(\d+\)", ""); + ds2item[4] = CustomOracleCodeFirst.GetOracleSqlTypeFullName(new object[] { row[1], row[2], row[3], row[4], row[5], row[6] }); + ds2item[5] = string.Concat(row[7]); + ds2item[6] = string.Concat(row[8]); + ds2item[7] = string.Concat(row[9]); + ds2item[8] = string.Concat(row[10]); + ds2.Add(ds2item); + } + var position = 0; + foreach (var row in ds2) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string type = string.Concat(row[2]); + //long max_length = long.Parse(string.Concat(row[3])); + string sqlType = string.Concat(row[4]); + var m_len = Regex.Match(sqlType, @"\w+\((\d+)"); + int max_length = m_len.Success ? int.Parse(m_len.Groups[1].Value) : -1; + bool is_nullable = string.Concat(row[5]) == "1"; + bool is_identity = string.Concat(row[6]) == "1"; + string comment = string.Concat(row[7]); + string defaultValue = string.Concat(row[8]); + if (max_length == 0) max_length = -1; + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + } + loc3[table_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[table_id], + Comment = comment, + DefaultValue = defaultValue, + Position = ++position + }); + loc3[table_id][column].DbType = this.GetDbType(loc3[table_id][column]); + loc3[table_id][column].CsType = this.GetCsTypeInfo(loc3[table_id][column]); + } + + CustomOracleCodeFirst.CreateOracleFunction(_orm); + sql = $@" +select +a.table_owner || '.' || a.table_name, +nvl(freesql_long_2_varchar(a.index_name, c.table_name, c.column_position), c.column_name), +c.index_name, +case when a.uniqueness = 'UNIQUE' then 1 else 0 end, +case when exists(select 1 from all_constraints where constraint_name = a.index_name and constraint_type = 'P') then 1 else 0 end, +0, +case when c.descend = 'DESC' then 1 else 0 end, +c.column_position +from all_indexes a, +all_ind_columns c +where a.index_name = c.index_name +and a.table_owner = c.table_owner +and a.table_name = c.table_name +and {(ignoreCase ? "lower(a.table_owner)" : "a.table_owner")} in ({databaseIn}) and {loc8} +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]).Trim('"'); + string index_id = string.Concat(row[2]); + bool is_unique = string.Concat(row[3]) == "1"; + bool is_primary_key = string.Concat(row[4]) == "1"; + bool is_clustered = string.Concat(row[5]) == "1"; + bool is_desc = string.Concat(row[6]) == "1"; + if (database.Length == 1) + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + if (is_primary_key) continue; + + Dictionary loc10 = null; + DbIndexInfo loc11 = null; + if (!indexColumns.TryGetValue(table_id, out loc10)) + indexColumns.Add(table_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(table_id, out loc10)) + uniqueColumns.Add(table_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + } + } + foreach (string table_id in indexColumns.Keys) + { + foreach (var column in indexColumns[table_id]) + loc2[table_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (string table_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[table_id]) + { + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); + loc2[table_id].UniquesDict.Add(column.Key, column.Value); + } + } + + if (tbname == null) + { + sql = $@" +select +a.owner || '.' || a.table_name, +c.column_name, +c.constraint_name, +b.owner || '.' || b.table_name, +1, +d.column_name + +-- a.owner 外键拥有者, +-- a.table_name 外键表, +-- c.column_name 外键列, +-- b.owner 主键拥有者, +-- b.table_name 主键表, +-- d.column_name 主键列, +-- c.constraint_name 外键名, +-- d.constraint_name 主键名 + +from +all_constraints a, +all_constraints b, +all_cons_columns c, --外键表 +all_cons_columns d --主键表 +where +a.r_constraint_name = b.constraint_name    +and a.constraint_type = 'R'    +and b.constraint_type = 'P'    +and a.r_owner = b.owner    +and a.constraint_name = c.constraint_name    +and b.constraint_name = d.constraint_name    +and a.owner = c.owner    +and a.table_name = c.table_name    +and b.owner = d.owner    +and b.table_name = d.table_name +and {(ignoreCase ? "lower(a.owner)" : "a.owner")} in ({databaseIn}) and {loc8} +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var fkColumns = new Dictionary>(); + foreach (var row in ds) + { + string table_id = string.Concat(row[0]); + string column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + string ref_table_id = string.Concat(row[3]); + bool is_foreign_key = string.Concat(row[4]) == "1"; + string referenced_column = string.Concat(row[5]); + if (database.Length == 1) + { + table_id = table_id.Substring(table_id.IndexOf('.') + 1); + ref_table_id = ref_table_id.Substring(ref_table_id.IndexOf('.') + 1); + } + if (loc3.ContainsKey(table_id) == false || loc3[table_id].ContainsKey(column) == false) continue; + var loc9 = loc3[table_id][column]; + if (loc2.ContainsKey(ref_table_id) == false) continue; + var loc10 = loc2[ref_table_id]; + var loc11 = loc3[ref_table_id][referenced_column]; + + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + } + + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); + + loc2.Clear(); + loc3.Clear(); + return loc1; + } + + public List GetEnumsByDatabase(params string[] database) + { + return new List(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleExpression.cs b/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleExpression.cs new file mode 100644 index 00000000..18cd30a7 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleExpression.cs @@ -0,0 +1,569 @@ +using FreeSql.Internal; +using System; +using System.Collections; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Custom.Oracle +{ + class CustomOracleExpression : CommonExpression + { + + public CustomOracleExpression(CommonUtils common) : base(common) { } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + if (arrOper.Type == typeof(byte[])) return $"dbms_lob.getlength({getExp(arrOper)})"; + break; + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (exp.Type.NullableTypeOrThis().ToString()) + { + //case "System.Boolean": return $"({getExp(operandExp)} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(operandExp)} as number)"; + case "System.Char": return $"substr(to_char({getExp(operandExp)}), 1, 1)"; + case "System.DateTime": return $"to_timestamp({getExp(operandExp)},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "System.Decimal": return $"cast({getExp(operandExp)} as number)"; + case "System.Double": return $"cast({getExp(operandExp)} as number)"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(operandExp)} as number)"; + case "System.Single": return $"cast({getExp(operandExp)} as number)"; + case "System.String": return $"to_char({getExp(operandExp)})"; + case "System.UInt16": + case "System.UInt32": + case "System.UInt64": return $"cast({getExp(operandExp)} as number)"; + case "System.Guid": + if (tsc.mapType == typeof(byte[])) return $"hextoraw({getExp(operandExp)})"; + return $"to_char({getExp(operandExp)})"; + } + } + break; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + //case "System.Boolean": return $"({getExp(callExp.Arguments[0])} not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Char": return $"substr(to_char({getExp(callExp.Arguments[0])}), 1, 1)"; + case "System.DateTime": return $"to_timestamp({getExp(callExp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Int16": + case "System.Int32": + case "System.Int64": + case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.UInt16": + case "System.UInt32": + case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as number)"; + case "System.Guid": + if (tsc.mapType == typeof(byte[])) return $"hextoraw({getExp(callExp.Arguments[0])})"; + return $"to_char({getExp(callExp.Arguments[0])})"; + } + return null; + case "NewGuid": + return null; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "cast(dbms_random.value*1000000000 as smallint)"; + return null; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "dbms_random.value"; + return null; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "dbms_random.value"; + return null; + case "ToString": + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"to_char({getExp(callExp.Object)})" : null; + return null; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substr({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArrayOrList()) + { + if (argIndex >= callExp.Arguments.Count) break; + tsc.SetMapColumnTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = objExp?.NodeType == ExpressionType.MemberAccess ? tsc.SetDbParamsReturnOld(null) : null; //#900 UseGenerateCommandParameterWithLambda(true) 子查询 bug、以及 #1173 参数化 bug + tsc.isNotSetMapColumnTmp = true; + var left = objExp == null ? null : getExp(objExp); + tsc.isNotSetMapColumnTmp = false; + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + if (oldDbParams != null) tsc.SetDbParamsReturnOld(oldDbParams); + switch (callExp.Method.Name) + { + case "Contains": + //判断 in //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("("); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + if (a % 500 == 499) arrSb.Append(" \r\n \r\n"); //500元素分割, 3空格\r\n4空格 + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append(")").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; + case "Today": return "trunc(systimestamp)"; + case "MinValue": return "to_timestamp('0001-01-01 00:00:00','YYYY-MM-DD HH24:MI:SS.FF6')"; + case "MaxValue": return "to_timestamp('9999-12-31 23:59:59','YYYY-MM-DD HH24:MI:SS.FF6')"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"trunc({left})"; + case "TimeOfDay": return $"({left}-trunc({left}))"; + case "DayOfWeek": return $"case when to_char({left},'D')='7' then 0 else cast(to_char({left},'D') as number) end"; + case "Day": return $"cast(to_char({left},'DD') as number)"; + case "DayOfYear": return $"cast(to_char({left},'DDD') as number)"; + case "Month": return $"cast(to_char({left},'MM') as number)"; + case "Year": return $"cast(to_char({left},'YYYY') as number)"; + case "Hour": return $"cast(to_char({left},'HH24') as number)"; + case "Minute": return $"cast(to_char({left},'MI') as number)"; + case "Second": return $"cast(to_char({left},'SS') as number)"; + case "Millisecond": return $"cast(to_char({left},'FF3') as number)"; + case "Ticks": return $"cast(to_char({left},'FF7') as number)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "numtodsinterval(0,'second')"; + case "MinValue": return "numtodsinterval(-233720368.5477580,'second')"; + case "MaxValue": return "numtodsinterval(233720368.5477580,'second')"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"extract(day from {left})"; + case "Hours": return $"extract(hour from {left})"; + case "Milliseconds": return $"cast(substr(extract(second from {left})-floor(extract(second from {left})),3,3) as number)"; + case "Minutes": return $"extract(minute from {left})"; + case "Seconds": return $"floor(extract(second from {left}))"; + case "Ticks": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*10000000"; + case "TotalDays": return $"extract(day from {left})"; + case "TotalHours": return $"(extract(day from {left})*24+extract(hour from {left}))"; + case "TotalMilliseconds": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))*1000"; + case "TotalMinutes": return $"(extract(day from {left})*1440+extract(hour from {left})*60+extract(minute from {left}))"; + case "TotalSeconds": return $"(extract(day from {left})*86400+extract(hour from {left})*3600+extract(minute from {left})*60+extract(second from {left}))"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception(CoreStrings.Not_Implemented_Expression_ParameterUseConstant(exp,exp.Arguments[0])); + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(SqlExtExtensions).GetMethod("StringJoinOracleGroupConcat"), + Expression.Convert(toListArgs1.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + return newToListSql; + } + break; + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + if (args0Value.Contains("%")) + { + if (exp.Method.Name == "StartsWith") return $"instr({args0Value}, {left}) = 1"; + if (exp.Method.Name == "EndsWith") return $"instr({args0Value}, {left}) = length({args0Value})"; + return $"instr({args0Value}, {left}) > 0"; + } + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(to_char({args0Value})||'%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'||to_char({args0Value}))")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) LIKE ('%'||to_char({args0Value})||'%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; + return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": + var indexOfFindStr = getExp(exp.Arguments[0]); + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") + { + var locateArgs1 = getExp(exp.Arguments[1]); + if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); + else locateArgs1 += "+1"; + return $"(instr({left}, {indexOfFindStr}, {locateArgs1}, 1)-1)"; + } + return $"(instr({left}, {indexOfFindStr}, 1, 1))-1"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])}, ' ')"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])}, ' ')"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; + if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; + } + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + if (exp.Method.Name == "Trim") left = $"trim(both {getExp(argsTrim01)} from {left})"; + if (exp.Method.Name == "TrimStart") left = $"ltrim({left},{getExp(argsTrim01)})"; + if (exp.Method.Name == "TrimEnd") left = $"rtrim({left},{getExp(argsTrim01)})"; + } + } + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceil({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": + if (exp.Arguments.Count > 1) return $"log({getExp(exp.Arguments[1])},{getExp(exp.Arguments[0])})"; + return $"log(2.7182818284590451,{getExp(exp.Arguments[0])})"; + case "Log10": return $"log(10,{getExp(exp.Arguments[0])})"; + case "Pow": return $"power({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + //case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))"; + case "DaysInMonth": return $"cast(to_char(last_day(to_date(({getExp(exp.Arguments[0])})||'-'||({getExp(exp.Arguments[1])})||'-01','yyyy-mm-dd')),'DD') as number)"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(mod({isLeapYearArgs1},4)=0 AND mod({isLeapYearArgs1},100)<>0 OR mod({isLeapYearArgs1},400)=0)"; + + case "Parse": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "AddDays": return $"({left}+{args1})"; + case "AddHours": return $"({left}+({args1})/24)"; + case "AddMilliseconds": return $"({left}+({args1})/86400000)"; + case "AddMinutes": return $"({left}+({args1})/1440)"; + case "AddMonths": return $"add_months({left},{args1})"; + case "AddSeconds": return $"({left}+({args1})/86400)"; + case "AddTicks": return $"({left}+({args1})/864000000000)"; + case "AddYears": return $"add_months({left},({args1})*12)"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"numtodsinterval(({left}+0)-({args1}+0),'day')"; + case "System.TimeSpan": return $"({left}-{args1})"; + } + break; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"extract(day from ({left}-({args1})))"; + case "ToString": + if (left.StartsWith("'") || left.EndsWith("'")) left = $"to_timestamp({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; + if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.FF6')"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS')"; + case "'yyyy-MM-dd HH:mm'": return $"to_char({left},'YYYY-MM-DD HH24:MI')"; + case "'yyyy-MM-dd HH'": return $"to_char({left},'YYYY-MM-DD HH24')"; + case "'yyyy-MM-dd'": return $"to_char({left},'YYYY-MM-DD')"; + case "'yyyy-MM'": return $"to_char({left},'YYYY-MM')"; + case "'yyyyMMddHHmmss'": return $"to_char({left},'YYYYMMDDHH24MISS')"; + case "'yyyyMMddHHmm'": return $"to_char({left},'YYYYMMDDHH24MI')"; + case "'yyyyMMddHH'": return $"to_char({left},'YYYYMMDDHH24')"; + case "'yyyyMMdd'": return $"to_char({left},'YYYYMMDD')"; + case "'yyyyMM'": return $"to_char({left},'YYYYMM')"; + case "'yyyy'": return $"to_char({left},'YYYY')"; + case "'HH:mm:ss'": return $"to_char({left},'HH24:MI:SS')"; + } + args1 = Regex.Replace(args1, "(yyyy|yy|MM|dd|HH|hh|mm|ss|tt)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"YYYY"; + case "yy": return $"YY"; + case "MM": return $"%_a1"; + case "dd": return $"%_a2"; + case "HH": return $"%_a3"; + case "hh": return $"%_a4"; + case "mm": return $"%_a5"; + case "ss": return $"SS"; + case "tt": return $"%_a6"; + } + return m.Groups[0].Value; + }); + var argsFinds = new[] { "YYYY", "YY", "%_a1", "%_a2", "%_a3", "%_a4", "%_a5", "SS", "%_a6" }; + var argsSpts = Regex.Split(args1, "(M|d|H|h|m|s|t)"); + for (var a = 0; a < argsSpts.Length; a++) + { + switch (argsSpts[a]) + { + case "M": argsSpts[a] = $"ltrim(to_char({left},'MM'),'0')"; break; + case "d": argsSpts[a] = $"case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end"; break; + case "H": argsSpts[a] = $"case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end"; break; + case "h": argsSpts[a] = $"case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end"; break; + case "m": argsSpts[a] = $"case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end"; break; + case "s": argsSpts[a] = $"case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end"; break; + case "t": argsSpts[a] = $"rtrim(to_char({left},'AM'),'M')"; break; + default: + var argsSptsA = argsSpts[a]; + if (argsSptsA.StartsWith("'")) argsSptsA = argsSptsA.Substring(1); + if (argsSptsA.EndsWith("'")) argsSptsA = argsSptsA.Remove(argsSptsA.Length - 1); + argsSpts[a] = argsFinds.Any(m => argsSptsA.Contains(m)) ? $"to_char({left},'{argsSptsA}')" : $"'{argsSptsA}'"; + break; + } + } + if (argsSpts.Length > 0) args1 = $"({string.Join(" || ", argsSpts.Where(a => a != "''"))})"; + return args1.Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); + } + } + return null; + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"extract(day from ({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])})))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"numtodsinterval(({getExp(exp.Arguments[0])})*{(long)60 * 60 * 24},'second')"; + case "FromHours": return $"numtodsinterval(({getExp(exp.Arguments[0])})*{(long)60 * 60},'second')"; + case "FromMilliseconds": return $"numtodsinterval(({getExp(exp.Arguments[0])})/1000,'second')"; + case "FromMinutes": return $"numtodsinterval(({getExp(exp.Arguments[0])})*60,'second')"; + case "FromSeconds": return $"numtodsinterval(({getExp(exp.Arguments[0])}),'second')"; + case "FromTicks": return $"numtodsinterval(({getExp(exp.Arguments[0])})/10000000,'second')"; + case "Parse": return $"cast({getExp(exp.Arguments[0])} as interval day(9) to second(7))"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as interval day(9) to second(7))"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"extract(day from ({left}-({args1})))"; + case "ToString": return $"to_char({left})"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + //case "ToBoolean": return $"({getExp(exp.Arguments[0])} not in ('0','false'))"; + case "ToByte": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToChar": return $"substr(to_char({getExp(exp.Arguments[0])}), 1, 1)"; + case "ToDateTime": return $"to_timestamp({getExp(exp.Arguments[0])},'YYYY-MM-DD HH24:MI:SS.FF6')"; + case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToInt16": + case "ToInt32": + case "ToInt64": + case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as number)"; + case "ToString": return $"to_char({getExp(exp.Arguments[0])})"; + case "ToUInt16": + case "ToUInt32": + case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as number)"; + } + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleProvider.cs b/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleProvider.cs new file mode 100644 index 00000000..8d1eedce --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleProvider.cs @@ -0,0 +1,51 @@ +using FreeSql.Internal.CommonProvider; +using System; +using System.Data.Common; +using System.Threading; + +namespace FreeSql.Custom.Oracle +{ + + public class CustomOracleProvider : BaseDbProvider, IFreeSql + { + public override ISelect CreateSelectProvider(object dywhere) => new CustomOracleSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new CustomOracleInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new CustomOracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new CustomOracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new CustomOracleInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); + + public CustomOracleProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) + { + this.InternalCommonUtils = new CustomOracleUtils(this); + this.InternalCommonExpression = new CustomOracleExpression(this.InternalCommonUtils); + + this.Ado = new CustomOracleAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); + this.Aop = new AopProvider(); + + this.DbFirst = new CustomOracleDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new CustomOracleCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + + //this.Aop.AuditValue += new EventHandler((_, e) => + //{ + // if (e.Value == null && e.Column.Attribute.IsPrimary == false && e.Column.Attribute.IsIdentity == false) + // e.Value = Utils.GetDataReaderValue(e.Property.PropertyType.NullableTypeOrThis(), e.Column.Attribute.DbDefautValue); + //}); + } + + ~CustomOracleProvider() => this.Dispose(); + int _disposeCounter; + public override void Dispose() + { + if (Interlocked.Increment(ref _disposeCounter) != 1) return; + try + { + (this.Ado as AdoProvider)?.Dispose(); + } + finally + { + FreeSqlCustomAdapterGlobalExtensions._dicCustomAdater.TryRemove(Ado.Identifier, out var tryada); + FreeSqlCustomAdapterGlobalExtensions._dicDbProviderFactory.TryRemove(Ado.Identifier, out var trydbpf); + } + } + } +} diff --git a/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleUtils.cs b/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleUtils.cs new file mode 100644 index 00000000..f1950fc7 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/Oracle/CustomOracleUtils.cs @@ -0,0 +1,133 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Globalization; + +namespace FreeSql.Custom.Oracle +{ + + class CustomOracleUtils : CommonUtils + { + DbProviderFactory Factory => FreeSqlCustomAdapterGlobalExtensions.GetDbProviderFactory(_orm); + + public CustomOracleUtils(IFreeSql orm) : base(orm) + { + } + + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + var dbtype = (DbType?)_orm.CodeFirst.GetDbInfo(type)?.type; + switch (dbtype) + { + case DbType.Boolean: + if (value == null) value = null; + else value = (bool)value == true ? 1 : 0; + dbtype = DbType.Int32; + break; + + case DbType.String: + case DbType.AnsiString: + case DbType.StringFixedLength: + case DbType.AnsiStringFixedLength: + value = string.Concat(value); + break; + } + var ret = Factory.CreateParameter(); + ret.ParameterName = QuoteParamterName(parameterName); + if (dbtype != null) ret.DbType = dbtype.Value; + ret.Value = value; + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => + { + var dbtype = (DbType?)_orm.CodeFirst.GetDbInfo(type)?.type; + switch (dbtype) + { + case DbType.Boolean: + if (value == null) value = null; + else value = (bool)value == true ? 1 : 0; + dbtype = DbType.Int32; + break; + + case DbType.String: + case DbType.AnsiString: + case DbType.StringFixedLength: + case DbType.AnsiStringFixedLength: + value = string.Concat(value); + break; + } + var ret = Factory.CreateParameter(); + ret.ParameterName = $":{name}"; + if (dbtype != null) ret.DbType = dbtype.Value; + ret.Value = value; + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatCustomOracle(args); + public override string QuoteSqlName(params string[] name) + { + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("\"") && nametrim.EndsWith("\"")) + return nametrim; + return $"\"{nametrim.Replace(".", "\".\"")}\""; + } + return $"\"{string.Join("\".\"", name)}\""; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; + } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); + public override string QuoteParamterName(string name) => $":{name}"; + public override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"trunc({left} / {right})"; + public override string Now => "systimestamp"; + public override string NowUtc => "sys_extract_utc(systimestamp)"; + + public override string QuoteWriteParamterAdapter(Type type, string paramterName) => paramterName; + protected override string QuoteReadColumnAdapter(Type type, Type mapType, string columnName) => columnName; + + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) + { + if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); + if (type == typeof(string)) + { + var valueString = value as string; + if (valueString != null) + { + if (valueString.Length < 4000) return string.Concat("'", valueString.Replace("'", "''"), "'"); + var pam = AppendParamter(specialParams, $"p_{specialParams?.Count}{specialParamFlag}", col, type, value); + return pam.ParameterName; + } + } + if (type == typeof(byte[])) + { + var valueBytes = value as byte[]; + if (valueBytes != null) + { + if (valueBytes.Length < 4000) return $"hextoraw('{CommonUtils.BytesSqlRaw(valueBytes)}')"; + var pam = AppendParamter(specialParams, $"p_{specialParams?.Count}{specialParamFlag}", col, type, value); + return pam.ParameterName; + } + } + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLDelete.cs b/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLDelete.cs new file mode 100644 index 00000000..b1fa46d3 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLDelete.cs @@ -0,0 +1,121 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Custom.PostgreSQL +{ + + class CustomPostgreSQLDelete : Internal.CommonProvider.DeleteProvider + { + public CustomPostgreSQLDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() + { + var ret = new List(); + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => + { + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(_orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) + { + this.ClearData(); + sbret.Clear(); + } + return ret; + } + +#if net40 +#else + async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) + { + var ret = new List(); + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => + { + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) + { + this.ClearData(); + sbret.Clear(); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLInsert.cs b/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLInsert.cs new file mode 100644 index 00000000..a62ab7c8 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLInsert.cs @@ -0,0 +1,217 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Custom.PostgreSQL +{ + + class CustomPostgreSQLInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public CustomPostgreSQLInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + internal IFreeSql InternalOrm => _orm; + internal TableInfo InternalTable => _table; + internal DbParameter[] InternalParams => _params; + internal DbConnection InternalConnection => _connection; + internal DbTransaction InternalTransaction => _transaction; + internal CommonUtils InternalCommonUtils => _commonUtils; + internal CommonExpression InternalCommonExpression => _commonExpression; + internal List InternalSource => _source; + internal Dictionary InternalIgnore => _ignore; + internal void InternalClearData() => ClearData(); + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); + if (identCols.Any() == false) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + ret = _orm.Ado.ExecuteNonQuery(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return 0; + } + sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 5000, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + long ret = 0; + Exception exception = null; + Aop.CurdBeforeEventArgs before = null; + + var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); + if (identCols.Any() == false) + { + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + ret = await _orm.Ado.ExecuteNonQueryAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return 0; + } + sql = string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)); + before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + try + { + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(sql).Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLInsertOrUpdate.cs b/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLInsertOrUpdate.cs new file mode 100644 index 00000000..2dbd92b4 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLInsertOrUpdate.cs @@ -0,0 +1,72 @@ +using FreeSql.Internal; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Text; + +namespace FreeSql.Custom.PostgreSQL +{ + + class CustomPostgreSQLInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public CustomPostgreSQLInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + var dbParams = new List(); + if (_sourceSql != null) + { + var data = new List(); + data.Add((T1)_table.Type.CreateInstanceGetDefaultValue()); + var sql = getInsertSql(data, false, false); + var sb = new StringBuilder(); + sb.Append(sql.Substring(0, sql.IndexOf(") VALUES"))); + sb.Append(") \r\n"); + WriteSourceSelectUnionAll(null, sb, null); + sb.Append(sql.Substring(sql.IndexOf("\r\nON CONFLICT(") + 2)); + return sb.ToString(); + } + if (_source?.Any() != true) return null; + + var sqls = new string[2]; + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = string.Join("\r\n\r\n;\r\n\r\n", ds.Item1.Select(a => getInsertSql(a, false, true))); + if (ds.Item2.Any()) sqls[1] = string.Join("\r\n\r\n;\r\n\r\n", ds.Item2.Select(a => getInsertSql(a, true, true))); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); + + string getInsertSql(List data, bool flagInsert, bool noneParameter) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(noneParameter) as Internal.CommonProvider.InsertProvider; + insert._source = data; + insert._table = _table; + insert._noneParameterFlag = flagInsert ? "cuc" : "cu"; + + string sql = ""; + if (IdentityColumn != null && flagInsert) sql = insert.ToSql(); + else + { + var ocdu = new CustomPostgreSQLOnConflictDoUpdate(insert.InsertIdentity()); + ocdu._tempPrimarys = _tempPrimarys; + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + ocdu.UpdateColumns(cols.Select(a => a.Attribute.Name).ToArray()); + if (_doNothing == true || cols.Any() == false) + ocdu.DoNothing(); + sql = ocdu.ToSql(); + } + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLOnConflictDoUpdate.cs b/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLOnConflictDoUpdate.cs new file mode 100644 index 00000000..b9c9c4cd --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLOnConflictDoUpdate.cs @@ -0,0 +1,209 @@ +using FreeSql.Aop; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Custom.PostgreSQL +{ + public class CustomPostgreSQLOnConflictDoUpdate where T1 : class + { + internal CustomPostgreSQLInsert _pgsqlInsert; + internal CustomPostgreSQLUpdate _pgsqlUpdatePriv; + internal CustomPostgreSQLUpdate _pgsqlUpdate => _pgsqlUpdatePriv ?? + (_pgsqlUpdatePriv = new CustomPostgreSQLUpdate(_pgsqlInsert.InternalOrm, _pgsqlInsert.InternalCommonUtils, _pgsqlInsert.InternalCommonExpression, null) { InternalTableAlias = "EXCLUDED" } + .NoneParameter().SetSource(_pgsqlInsert.InternalSource) as CustomPostgreSQLUpdate); + internal ColumnInfo[] _tempPrimarys; + bool _doNothing; + + public CustomPostgreSQLOnConflictDoUpdate(IInsert insert, Expression> columns = null) + { + _pgsqlInsert = insert as CustomPostgreSQLInsert; + if (_pgsqlInsert == null) throw new Exception(CoreStrings.S_Features_Unique("OnConflictDoUpdate", "Odbc/PostgreSQL")); + if (_pgsqlInsert._noneParameterFlag == "c") _pgsqlInsert._noneParameterFlag = "cu"; + + if (columns != null) + { + var colsList = new List(); + var cols = _pgsqlInsert.InternalCommonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, null, columns?.Body, false, null).ToDictionary(a => a, a => true); + foreach (var col in _pgsqlInsert.InternalTable.Columns.Values) + if (cols.ContainsKey(col.Attribute.Name)) + colsList.Add(col); + _tempPrimarys = colsList.ToArray(); + } + if (_tempPrimarys == null || _tempPrimarys.Any() == false) + _tempPrimarys = _pgsqlInsert.InternalTable.Primarys; + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.S_OnConflictDoUpdate_MustIsPrimary); + } + + protected void ClearData() + { + _pgsqlInsert.InternalClearData(); + _pgsqlUpdatePriv = null; + } + + public CustomPostgreSQLOnConflictDoUpdate IgnoreColumns(Expression> columns) + { + _pgsqlUpdate.IgnoreColumns(columns); + return this; + } + public CustomPostgreSQLOnConflictDoUpdate UpdateColumns(Expression> columns) + { + _pgsqlUpdate.UpdateColumns(columns); + return this; + } + public CustomPostgreSQLOnConflictDoUpdate IgnoreColumns(string[] columns) + { + _pgsqlUpdate.IgnoreColumns(columns); + return this; + } + public CustomPostgreSQLOnConflictDoUpdate UpdateColumns(string[] columns) + { + _pgsqlUpdate.UpdateColumns(columns); + return this; + } + + public CustomPostgreSQLOnConflictDoUpdate Set(Expression> column, TMember value) + { + _pgsqlUpdate.Set(column, value); + return this; + } + //由于表达式解析问题,ON CONFLICT("id") DO UPDATE SET 需要指定表别名,如 Set(a => a.Clicks + 1) 解析会失败 + //暂时不开放这个功能,如有需要使用 SetRaw("click = t.click + 1") 替代该操作 + //public OnConflictDoUpdate Set(Expression> exp) + //{ + // _pgsqlUpdate.Set(exp); + // return this; + //} + public CustomPostgreSQLOnConflictDoUpdate SetRaw(string sql) + { + _pgsqlUpdate.SetRaw(sql); + return this; + } + + public CustomPostgreSQLOnConflictDoUpdate DoNothing() + { + _doNothing = true; + return this; + } + + public string ToSql() + { + var sb = new StringBuilder(); + sb.Append(_pgsqlInsert.ToSql()).Append("\r\nON CONFLICT("); + for (var a = 0; a < _tempPrimarys.Length; a++) + { + if (a > 0) sb.Append(", "); + sb.Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_tempPrimarys[a].Attribute.Name)); + } + if (_doNothing) + { + sb.Append(") DO NOTHING"); + } + else + { + sb.Append(") DO UPDATE SET\r\n"); + + var sbSetEmpty = _pgsqlUpdate.InternalSbSet.Length == 0; + var sbSetIncrEmpty = _pgsqlUpdate.InternalSbSetIncr.Length == 0; + if (sbSetEmpty == false || sbSetIncrEmpty == false) + { + if (sbSetEmpty == false) sb.Append(_pgsqlUpdate.InternalSbSet.ToString().Substring(2)); + if (sbSetIncrEmpty == false) sb.Append(sbSetEmpty ? _pgsqlUpdate.InternalSbSetIncr.ToString().Substring(2) : _pgsqlUpdate.InternalSbSetIncr.ToString()); + } + else + { + var colidx = 0; + foreach (var col in _pgsqlInsert.InternalTable.Columns.Values) + { + if (col.Attribute.IsPrimary || _pgsqlUpdate.InternalIgnore.ContainsKey(col.Attribute.Name)) continue; + + if (colidx > 0) sb.Append(", \r\n"); + + if (col.Attribute.IsVersion == true && col.Attribute.MapType != typeof(byte[])) + { + var field = _pgsqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = ").Append(_pgsqlInsert.InternalCommonUtils.QuoteSqlName(_pgsqlInsert.InternalTable.DbName)).Append(".").Append(field).Append(" + 1"); + } + else if (_pgsqlInsert.InternalIgnore.ContainsKey(col.Attribute.Name)) + { + var caseWhen = _pgsqlUpdate.InternalWhereCaseSource(col.CsName, sqlval => sqlval).Trim(); + sb.Append(caseWhen); + if (caseWhen.EndsWith(" END")) _pgsqlUpdate.InternalToSqlCaseWhenEnd(sb, col); + } + else + { + var field = _pgsqlInsert.InternalCommonUtils.QuoteSqlName(col.Attribute.Name); + sb.Append(field).Append(" = EXCLUDED.").Append(field); + } + ++colidx; + } + } + } + + return sb.ToString(); + } + + public long ExecuteAffrows() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_pgsqlInsert.InternalTable.Type, _pgsqlInsert.InternalTable, CurdType.Insert, sql, _pgsqlInsert.InternalParams); + _pgsqlInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_pgsqlInsert, before); + long ret = 0; + Exception exception = null; + try + { + ret = _pgsqlInsert.InternalOrm.Ado.ExecuteNonQuery(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert._commandTimeout, _pgsqlInsert.InternalParams); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _pgsqlInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_pgsqlInsert, after); + ClearData(); + } + return ret; + } + +#if net40 +#else + async public Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + var before = new CurdBeforeEventArgs(_pgsqlInsert.InternalTable.Type, _pgsqlInsert.InternalTable, CurdType.Insert, sql, _pgsqlInsert.InternalParams); + _pgsqlInsert.InternalOrm.Aop.CurdBeforeHandler?.Invoke(_pgsqlInsert, before); + long ret = 0; + Exception exception = null; + try + { + ret = await _pgsqlInsert.InternalOrm.Ado.ExecuteNonQueryAsync(_pgsqlInsert.InternalConnection, _pgsqlInsert.InternalTransaction, CommandType.Text, sql, _pgsqlInsert._commandTimeout, _pgsqlInsert.InternalParams, cancellationToken); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new CurdAfterEventArgs(before, exception, ret); + _pgsqlInsert.InternalOrm.Aop.CurdAfterHandler?.Invoke(_pgsqlInsert, after); + ClearData(); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLSelect.cs b/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLSelect.cs new file mode 100644 index 00000000..68628aef --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLSelect.cs @@ -0,0 +1,214 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Custom.PostgreSQL +{ + + class CustomPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select1Provider + { + + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereGlobalFilter.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + sb.Append(field).Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); + } + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + switch (tb.Type) + { + case SelectTableInfoType.Parent: + case SelectTableInfoType.RawJoin: + continue; + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND ").Append(_tables[0].Cascade); + + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + sb.Append(_orderby); + if (_limit > 0) + sb.Append(" \r\nlimit ").Append(_limit); + if (_skip > 0) + sb.Append(" \r\noffset ").Append(_skip); + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.Append(_tosqlAppendContent).ToString(); + } + + public CustomPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); CustomPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); CustomPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); CustomPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); CustomPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); CustomPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); CustomPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); CustomPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); CustomPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); CustomPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); CustomPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); CustomPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); CustomPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); CustomPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); CustomPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcPostgreSQLSelect(_orm, _commonUtils, _commonExpression, null); CustomPostgreSQLSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcPostgreSQLSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public OdbcPostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomPostgreSQLSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } +} diff --git a/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLUpdate.cs b/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLUpdate.cs new file mode 100644 index 00000000..cef51caa --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/PostgreSQL/Curd/CustomPostgreSQLUpdate.cs @@ -0,0 +1,187 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Custom.PostgreSQL +{ + + class CustomPostgreSQLUpdate : Internal.CommonProvider.UpdateProvider + { + + public CustomPostgreSQLUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + internal string InternalTableAlias { get; set; } + internal StringBuilder InternalSbSet => _set; + internal StringBuilder InternalSbSetIncr => _setIncr; + internal Dictionary InternalIgnore => _ignore; + internal void InternalResetSource(List source) => _source = source; + internal string InternalWhereCaseSource(string CsName, Func thenValue) => WhereCaseSource(CsName, thenValue); + internal void InternalToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) => ToSqlCaseWhenEnd(sb, col); + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000); + + protected override List RawExecuteUpdated() + { + var ret = new List(); + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => + { + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); + return ret; + } + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (primarys.Length == 1) + { + var pk = primarys.First(); + if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); + caseWhen.Append(_commonUtils.RereadColumn(pk, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in primarys) + { + if (pkidx > 0) caseWhen.Append(" || '+' || "); + if (string.IsNullOrEmpty(InternalTableAlias) == false) caseWhen.Append(InternalTableAlias).Append("."); + caseWhen.Append(_commonUtils.RereadColumn(pk, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::text"); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", primarys[0].GetDbValue(d))); + return; + } + sb.Append("("); + var pkidx = 0; + foreach (var pk in primarys) + { + if (pkidx > 0) sb.Append(" || '+' || "); + sb.Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))).Append("::text"); + ++pkidx; + } + sb.Append(")"); + } + + protected override void ToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) + { + if (_noneParameter == false) return; + if (col.Attribute.MapType == typeof(string)) + { + sb.Append("::text"); + return; + } + var dbtype = _commonUtils.CodeFirst.GetDbInfo(col.Attribute.MapType)?.dbtype; + if (dbtype == null) return; + + sb.Append("::").Append(dbtype); + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken); + + async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) + { + var ret = new List(); + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => + { + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" RETURNING "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.Append(sbret).ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLAdo/CustomPostgreSQLAdo.cs b/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLAdo/CustomPostgreSQLAdo.cs new file mode 100644 index 00000000..218493bf --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLAdo/CustomPostgreSQLAdo.cs @@ -0,0 +1,70 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using FreeSql.Internal.ObjectPool; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data.Common; +using System.Text; +using System.Threading; + +namespace FreeSql.Custom.PostgreSQL +{ + class CustomPostgreSQLAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + DbProviderFactory Factory => FreeSqlCustomAdapterGlobalExtensions.GetDbProviderFactory(_util._orm); + + public CustomPostgreSQLAdo() : base(DataType.OdbcPostgreSQL, null, null) { } + public CustomPostgreSQLAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcPostgreSQL, masterConnectionString, slaveConnectionStrings) + { + base._util = util; + if (connectionFactory != null) + { + var pool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.SqlServer, connectionFactory); + MasterPool = pool; + return; + } + throw new Exception(CoreStrings.S_CustomAdapter_OnlySuppport_UseConnectionFactory); + } + + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) + param = Utils.GetDataReaderValue(mapType, param); + + if (param is bool || param is bool?) + return (bool)param ? "'t'" : "'f'"; + else if (param is string) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "'"); + else if (param is TimeSpan || param is TimeSpan?) + return ((TimeSpan)param).Ticks / 10; + else if (param is byte[]) + return $"'\\x{CommonUtils.BytesSqlRaw(param as byte[])}'"; + else if (param is IEnumerable) + return AddslashesIEnumerable(param, mapType, mapColumn); + + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + } + + public override DbCommand CreateCommand() + { + return Factory.CreateCommand(); + } + + public override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) + { + pool.Return(conn); + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLCodeFirst.cs new file mode 100644 index 00000000..80ccfb24 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLCodeFirst.cs @@ -0,0 +1,480 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; + +namespace FreeSql.Custom.PostgreSQL +{ + + class CustomPostgreSQLCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; } + public CustomPostgreSQLCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + + static object _dicCsToDbLock = new object(); + static Dictionary> _dicCsToDb = new Dictionary>() { + + { typeof(sbyte).FullName, CsToDb.New(DbType.SByte, "int2","int2 NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(DbType.SByte, "int2", "int2", false, true, null) }, + { typeof(short).FullName, CsToDb.New(DbType.Int16, "int2","int2 NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(DbType.Int16, "int2", "int2", false, true, null) }, + { typeof(int).FullName, CsToDb.New(DbType.Int32, "int4","int4 NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(DbType.Int32, "int4", "int4", false, true, null) }, + { typeof(long).FullName, CsToDb.New(DbType.Int64, "int8","int8 NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(DbType.Int64, "int8", "int8", false, true, null) }, + + { typeof(byte).FullName, CsToDb.New(DbType.Byte, "int2","int2 NOT NULL", false, false, 0) },{ typeof(byte?).FullName, CsToDb.New(DbType.Byte, "int2", "int2", false, true, null) }, + { typeof(ushort).FullName, CsToDb.New(DbType.UInt16, "int4","int4 NOT NULL", false, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(DbType.UInt16, "int4", "int4", false, true, null) }, + { typeof(uint).FullName, CsToDb.New(DbType.UInt32, "int8","int8 NOT NULL", false, false, 0) },{ typeof(uint?).FullName, CsToDb.New(DbType.UInt32, "int8", "int8", false, true, null) }, + { typeof(ulong).FullName, CsToDb.New(DbType.UInt64, "numeric","numeric(20,0) NOT NULL", false, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(DbType.UInt64, "numeric", "numeric(20,0)", false, true, null) }, + + { typeof(float).FullName, CsToDb.New(DbType.Single, "float4","float4 NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(DbType.Single, "float4", "float4", false, true, null) }, + { typeof(double).FullName, CsToDb.New(DbType.Double, "float8","float8 NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(DbType.Double, "float8", "float8", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(DbType.Decimal, "numeric", "numeric(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(DbType.Decimal, "numeric", "numeric(10,2)", false, true, null) }, + + { typeof(string).FullName, CsToDb.New(DbType.String, "varchar", "varchar(255)", false, null, "") }, + { typeof(char).FullName, CsToDb.New(DbType.AnsiString, "char", "char(1) NULL", false, null, '\0') }, + + { typeof(TimeSpan).FullName, CsToDb.New(DbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(DbType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(DbType.DateTime, "timestamp", "timestamp NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(DbType.DateTime, "timestamp", "timestamp", false, true, null) }, + + { typeof(bool).FullName, CsToDb.New(DbType.Boolean, "bool","bool NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(DbType.Boolean, "bool","bool", null, true, null) }, + { typeof(Byte[]).FullName, CsToDb.New(DbType.Binary, "bytea", "bytea", false, null, new byte[0]) }, + + { typeof(Guid).FullName, CsToDb.New(DbType.Guid, "uuid", "uuid NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(DbType.Guid, "uuid", "uuid", false, true, null) }, + }; + + public override DbInfoResult GetDbInfo(Type type) + { + var isarray = type.FullName != "System.Byte[]" && type.IsArray; + var elementType = isarray ? type.GetElementType() : type; + var info = GetDbInfoNoneArray(elementType); + if (info == null) return null; + return new DbInfoResult((int)info.type, info.dbtype, info.dbtypeFull, info.isnullable, info.defaultValue); + } + CsToDb GetDbInfoNoneArray(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return trydc; + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + CsToDb.New(DbType.Int32, "int8", $"int8{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(DbType.Int64, "int4", $"int4{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return newItem; + } + return null; + } + + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) + { + var sb = new StringBuilder(); + var seqcols = new List>(); //序列 + + var isPg96 = true; + var isPg10 = (_orm.DbFirst as CustomPostgreSQLDbFirst).IsPg10; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + isPg96 = CustomPostgreSQLDbFirst.PgVersionIs96(conn.Value.ServerVersion); + } + + foreach (var obj in objects) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception(CoreStrings.S_Type_IsNot_Migrable(obj.entityType.FullName)); + if (tb.Columns.Any() == false) throw new Exception(CoreStrings.S_Type_IsNot_Migrable_0Attributes(obj.entityType.FullName)); + var tbname = _commonUtils.SplitTableName(tb.DbName); + if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; + + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { "public", tboldname[0] }; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); + if (tbtmpname?.Length == 1) tbtmpname = new[] { "public", tbtmpname[0] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1]) + { + tbname = tbtmpname; + tboldname = null; + } + } + //codefirst 不支持表名、模式名、数据库名中带 . + + if (string.Compare(tbname[0], "public", true) != 0 && _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(" select 1 from pg_namespace where nspname={0}", tbname[0])) == null) //创建模式 + sb.Append("CREATE SCHEMA IF NOT EXISTS ").Append(tbname[0]).Append(";\r\n"); + + 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) + { + //创建表 + var createTableName = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); + sb.Append("CREATE TABLE IF NOT EXISTS ").Append(createTableName).Append(" ( "); + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true) + { + if (isPg10) sb.Append(" GENERATED BY DEFAULT AS IDENTITY"); + else seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); + } + sb.Append(","); + } + if (tb.Primarys.Any()) + { + var pkname = $"{tbname[0]}_{tbname[1]}_pkey"; + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\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 sql = _commonUtils.FormatSql($@" +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 and t.typinput::varchar = 'array_in' then t2.typname else t.typname end, +case when a.attnotnull then '0' else '1' end as is_nullable, +--e.adsrc, +(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid limit 1) is_identity, +a.attndims, +d.description as comment{(isPg10 ? ", a.attidentity" : "")} +from pg_class c +inner join pg_attribute a on a.attnum > 0 and a.attrelid = c.oid +inner join pg_type t on t.oid = a.atttypid +left join pg_type t2 on t2.oid = t.typelem +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}}", tboldname ?? tbname); + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + var tbstruct = ds.ToDictionary(a => string.Concat(a[0]), a => + { + var attndims = int.Parse(string.Concat(a[6])); + var type = string.Concat(a[1]); + var sqlType = string.Concat(a[3]); + var max_length = long.Parse(string.Concat(a[2])); + switch (sqlType.ToLower()) + { + case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; + default: max_length *= 8; break; + } + if (type.StartsWith("_")) + { + type = type.Substring(1); + if (attndims == 0) attndims++; + } + if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); + var is_identity_pg9 = string.Concat(a[5]).StartsWith(@"nextval('") && (string.Concat(a[5]).EndsWith(@"'::regclass)") || string.Concat(a[5]).EndsWith(@"')")); + return new + { + column = string.Concat(a[0]), + sqlType = string.Concat(sqlType), + max_length = long.Parse(string.Concat(a[2])), + is_nullable = string.Concat(a[4]) == "1", + is_identity_pg9 = is_identity_pg9, + is_identity = is_identity_pg9 + || isPg10 && new[] { "a", "d" }.Contains(string.Concat(a[8])), //pg10 GENERATED { BY DEFAULT | AWAYS } AS IDENTITY + attndims, + comment = string.Concat(a[7]) + }; + }, StringComparer.CurrentCultureIgnoreCase); + + if (istmpatler == false) + { + foreach (var tbcol in tb.ColumnsByPosition) + { + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + var sqlTypeSize = tbstructcol.sqlType; + if (sqlTypeSize.Contains("(") == false) + { + switch (sqlTypeSize.ToLower()) + { + case "bit": + case "varbit": + case "bpchar": + case "varchar": + sqlTypeSize = $"{sqlTypeSize}({tbstructcol.max_length})"; break; + } + } + if (tbcol.Attribute.DbType.StartsWith(sqlTypeSize, StringComparison.CurrentCultureIgnoreCase) == false || + tbcol.Attribute.DbType.Contains("[]") != (tbstructcol.attndims > 0)) + 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.Split(' ').First()).Append(";\r\n"); + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + { + if (tbcol.Attribute.IsNullable != true || tbcol.Attribute.IsNullable == true && tbcol.Attribute.IsPrimary == false) + { + if (tbcol.Attribute.IsNullable == false) + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" = ").Append(tbcol.DbDefaultValue).Append(" WHERE ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" IS NULL;\r\n"); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(tbcol.Attribute.IsNullable == true ? "DROP" : "SET").Append(" NOT NULL;\r\n"); + } + } + if (tbcol.Attribute.IsIdentity != tbstructcol.is_identity) + { + if (isPg10) + { + if (tbstructcol.is_identity) + { + if (tbstructcol.is_identity_pg9) + seqcols.Add(NativeTuple.Create(tbcol, tbname, false)); + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" DROP IDENTITY IF EXISTS;\r\n"); + } + else + { + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ADD GENERATED BY DEFAULT AS IDENTITY"); + var maxval = _orm.Ado.QuerySingle($"select max({_commonUtils.QuoteSqlName(tbcol.Attribute.Name)}) from {_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")}"); + if (maxval > 0) + sbalter.Append(" (START ").Append(maxval + 1).Append(")"); + sbalter.Append(";\r\n"); + } + } + else + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + } + if (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + //修改列名 + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" RENAME COLUMN ").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" TO ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(";\r\n"); + if (isCommentChanged) + sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + continue; + } + //添加列 + 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.Split(' ').First()).Append(";\r\n"); + sbalter.Append("UPDATE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" SET ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" = ").Append(tbcol.DbDefaultValue).Append(";\r\n"); + if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); + if (tbcol.Attribute.IsIdentity == true) + { + if (isPg10) + sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ADD GENERATED BY DEFAULT AS IDENTITY;\r\n"); + else + seqcols.Add(NativeTuple.Create(tbcol, tbname, tbcol.Attribute.IsIdentity == true)); + } + if (string.IsNullOrEmpty(tbcol.Comment) == false) sbalter.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + var dsuksql = _commonUtils.FormatSql($@" +select +c.attname, +b.relname, +{(isPg96 ? "case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end" : "0")} IsDesc, +case when indisunique = 't' then 1 else 0 end IsUnique +from pg_index a +inner join pg_class b on b.oid = a.indexrelid +inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid +inner join pg_namespace ns on ns.oid = b.relnamespace +inner join pg_class d on d.oid = a.indrelid +where ns.nspname in ({{0}}) and d.relname in ({{1}}) and a.indisprimary = 'f'", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); + foreach (var uk in tb.Indexes) + { + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var ukname = ReplaceIndexName(uk.Name, tbname[1]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => uk.Columns.Where(b => (a[3] == "1") == uk.IsUnique && string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && ((a[2] == "1") == b.IsDesc || isPg96 == false)).Any()).Count() != uk.Columns.Length) + { + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(";\r\n"); + sbalter.Append("CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } + sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); + } + } + } + if (istmpatler == false) + { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select +d.description +from pg_class a +inner join pg_namespace b on b.oid = a.relnamespace +left join pg_description d on d.objoid = a.oid and objsubid = 0 +where b.nspname not in ('pg_catalog', 'information_schema') and a.relkind in ('r') and b.nspname = {0} and a.relname = {1} +and b.nspname || '.' || a.relname not in ('public.geography_columns','public.geometry_columns','public.raster_columns','public.raster_overviews')", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sbalter.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + + sb.Append(sbalter); + continue; + } + var oldpk = _orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select pg_constraint.conname as pk_name from pg_constraint +inner join pg_class on pg_constraint.conrelid = pg_class.oid +inner join pg_namespace on pg_namespace.oid = pg_class.relnamespace +where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contype='p' +", tbname))?.ToString(); + if (string.IsNullOrEmpty(oldpk) == false) + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(oldpk).Append(";\r\n"); + + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + 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.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true) + { + if (isPg10) sb.Append(" GENERATED BY DEFAULT AS IDENTITY"); + else seqcols.Add(NativeTuple.Create(tbcol, tbname, true)); + } + sb.Append(","); + } + if (tb.Primarys.Any()) + { + var pkname = $"{tbname[0]}_{tbname[1]}_pkey"; + sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(pkname)).Append(" PRIMARY KEY ("); + foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append("),"); + } + sb.Remove(sb.Length - 1, 1); + sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); + } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); + foreach (var tbcol in tb.ColumnsByPosition) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\nSELECT "); + foreach (var tbcol in tb.ColumnsByPosition) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"coalesce({insertvalue},{tbcol.DbDefaultValue})"; + } + else if (tbcol.Attribute.IsNullable == false) + insertvalue = tbcol.DbDefaultValue; + 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 uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } + if (isPg10) + { + foreach (var tbcol in tb.ColumnsByPosition) + { + if (tbcol.Attribute.IsIdentity) + { + var maxval = _orm.Ado.QuerySingle($"select max({_commonUtils.QuoteSqlName(tbcol.Attribute.Name)}) from {tablename}"); + if (maxval > 0) + { + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET GENERATED BY DEFAULT"); + sb.Append(" RESTART ").Append(maxval + 1).Append(""); + sb.Append(";\r\n"); + } + } + } + } + } + foreach (var seqcol in seqcols) + { + var tbname = seqcol.Item2; + var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name").ToLower(); + 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;\r\n"); + sb.Append("DROP SEQUENCE IF EXISTS ").Append(seqname).Append(";\r\n"); + if (seqcol.Item3) + { + 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(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLDbFirst.cs new file mode 100644 index 00000000..e4a67837 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLDbFirst.cs @@ -0,0 +1,554 @@ +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Custom.PostgreSQL +{ + class CustomPostgreSQLDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public CustomPostgreSQLDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public bool IsPg10 => ServerVersion >= 10; + public int ServerVersion + { + get + { + if (_ServerVersionValue == 0 && _orm.Ado.MasterPool != null) + using (var conn = _orm.Ado.MasterPool.Get()) + { + try + { + _ServerVersionValue = int.Parse(conn.Value.ServerVersion.Split('.')[0]); + } + catch + { + _ServerVersionValue = 9; + } + } + return _ServerVersionValue; + } + } + int _ServerVersionValue = 0; + + public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column); + DbType GetSqlDbType(DbColumnInfo column) + { + var dbtype = column.DbTypeText; + var isarray = dbtype?.EndsWith("[]") == true; + if (isarray) dbtype = dbtype.Remove(dbtype.Length - 2); + DbType ret = DbType.String; + switch (dbtype?.ToLower().TrimStart('_')) + { + case "int2": ret = DbType.Int16; break; + case "int4": ret = DbType.Int32; break; + case "int8": ret = DbType.Int64; break; + case "numeric": ret = DbType.Decimal; break; + case "float4": ret = DbType.Single; break; + case "float8": ret = DbType.Double; break; + case "money": ret = DbType.Decimal; break; + + case "bpchar": ret = DbType.AnsiString; break; + case "varchar": ret = DbType.String; break; + case "text": ret = DbType.String; break; + + case "timestamp": ret = DbType.DateTime; break; + case "timestamptz": ret = DbType.DateTime; break; + case "date": ret = DbType.Date; break; + case "time": ret = DbType.Time; break; + case "timetz": ret = DbType.Time; break; + case "interval": ret = DbType.Time; break; + + case "bool": ret = DbType.Boolean; break; + case "bytea": ret = DbType.Binary; break; + case "bit": ret = DbType.Boolean; break; + case "varbit": ret = DbType.Binary; break; + + case "json": ret = DbType.String; break; + case "jsonb": ret = DbType.String; break; + case "uuid": ret = DbType.Guid; break; + } + return ret; + } + + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)DbType.Boolean, new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + + { (int)DbType.SByte, new DbToCs("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetInt16") }, + { (int)DbType.Int16, new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)DbType.Int32, new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)DbType.Int64, new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + + { (int)DbType.Byte, new DbToCs("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { (int)DbType.UInt16, new DbToCs("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") }, + { (int)DbType.UInt32, new DbToCs("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") }, + { (int)DbType.UInt64, new DbToCs("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetInt64") }, + + { (int)DbType.Decimal, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)DbType.Single, new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + { (int)DbType.Double, new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + + { (int)DbType.AnsiString, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)DbType.String, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + + { (int)DbType.DateTime, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)DbType.Date, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)DbType.Time, new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + + { (int)DbType.Binary, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + { (int)DbType.Guid, new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid", typeof(Guid), typeof(Guid?), "{0}", "GetString") }, + }; + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + var sql = @" select datname from pg_database where datname not in ('template1', 'template0')"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); + } + + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $" select 1 from pg_tables a inner join pg_namespace b on b.nspname = a.schemaname where {(ignoreCase ? "lower(b.nspname)" : "b.nspname")}={_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(a.tablename)" : "a.tablename")}={_commonUtils.FormatSql("{0}", tbname[1])}"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) + { + var olddatabase = ""; + var is96 = true; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + olddatabase = conn.Value.Database; + is96 = PgVersionIs96(conn.Value.ServerVersion); + } + string[] tbname = null; + string[] dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) tbname = new[] { "public", tbname[0] }; + if (ignoreCase) tbname = tbname.Select(a => a.ToLower()).ToArray(); + dbs = new[] { olddatabase }; + } + var tables = new List(); + + foreach (var db in dbs) + { + if (string.IsNullOrEmpty(db) || string.Compare(db, olddatabase, true) != 0) continue; + + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + + var sql = $@" +{(tbname == null ? "" : $"select * from (")}select +b.nspname || '.' || a.tablename, +a.schemaname, +a.tablename , +d.description, +'TABLE' +from pg_tables a +inner join pg_namespace b on b.nspname = a.schemaname +inner join pg_class c on c.relnamespace = b.oid and c.relname = a.tablename +left join pg_description d on d.objoid = c.oid and objsubid = 0 +where a.schemaname not in ('pg_catalog', 'information_schema', 'topology') +and b.nspname || '.' || a.tablename not in ('public.spatial_ref_sys') + +union all + +select +b.nspname || '.' || a.relname, +b.nspname, +a.relname, +d.description, +'VIEW' +from pg_class a +inner join pg_namespace b on b.oid = a.relnamespace +left join pg_description d on d.objoid = a.oid and objsubid = 0 +where b.nspname not in ('pg_catalog', 'information_schema') and a.relkind in ('m','v') +and b.nspname || '.' || a.relname not in ('public.geography_columns','public.geometry_columns','public.raster_columns','public.raster_overviews') +{(tbname == null ? "" : $") ft_dbf where {(ignoreCase ? "lower(schemaname)" : "schemaname")}={_commonUtils.FormatSql("{0}", tbname[0])} and {(ignoreCase ? "lower(tablename)" : "tablename")}={_commonUtils.FormatSql("{0}", tbname[1])}")}"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var owner = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + Enum.TryParse(string.Concat(row[4]), out var type); + loc2.Add(object_id, new DbTableInfo { Id = object_id.ToString(), Schema = owner, Name = table, Comment = comment, Type = type }); + loc3.Add(object_id, new Dictionary()); + switch (type) + { + case DbTableType.VIEW: + case DbTableType.TABLE: + loc6_1000.Add(object_id); + if (loc6_1000.Count >= 500) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } + break; + case DbTableType.StoreProcedure: + loc66_1000.Add(object_id); + if (loc66_1000.Count >= 500) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } + break; + } + } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + + if (loc6.Count == 0) return loc1; + var loc8 = new StringBuilder().Append("("); + for (var loc8idx = 0; loc8idx < loc6.Count; loc8idx++) + { + if (loc8idx > 0) loc8.Append(" OR "); + loc8.Append("a.table_name in ("); + for (var loc8idx2 = 0; loc8idx2 < loc6[loc8idx].Length; loc8idx2++) + { + if (loc8idx2 > 0) loc8.Append(","); + loc8.Append($"'{loc6[loc8idx][loc8idx2]}'"); + } + loc8.Append(")"); + } + loc8.Append(")"); + + sql = $@" +select +ns.nspname || '.' || c.relname as id, +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, +--e.adsrc as is_identity, pg12以下 +(select pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = e.adrelid and adnum = e.adnum limit 1) is_identity, +d.description as comment, +a.attndims, +case when t.typelem = 0 then t.typtype else t2.typtype end, +ns2.nspname, +a.attnum{(IsPg10 ? ", a.attidentity" : "")} +from pg_class c +inner join pg_attribute a on a.attnum > 0 and a.attrelid = c.oid +inner join pg_type t on t.oid = a.atttypid +left join pg_type t2 on t2.oid = t.typelem +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 {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || c.relname")}"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var column = string.Concat(row[1]); + var type = string.Concat(row[2]); + var max_length = int.Parse(string.Concat(row[3])); + var sqlType = string.Concat(row[4]); + var is_nullable = string.Concat(row[5]) == "1"; + var is_identity = string.Concat(row[6]).StartsWith(@"nextval('") && (string.Concat(row[6]).EndsWith(@"'::regclass)") || string.Concat(row[6]).EndsWith(@"')")) + || IsPg10 && new[] { "a", "d" }.Contains(string.Concat(row[12])); //pg10 GENERATED { BY DEFAULT | AWAYS } AS IDENTITY + var comment = string.Concat(row[7]); + var defaultValue = string.Concat(row[6]); + int attndims = int.Parse(string.Concat(row[8])); + string typtype = string.Concat(row[9]); + string owner = string.Concat(row[10]); + int attnum = int.Parse(string.Concat(row[11])); + switch (sqlType.ToLower()) + { + case "bool": case "name": case "bit": case "varbit": case "bpchar": case "varchar": case "bytea": case "text": case "uuid": break; + default: max_length *= 8; break; + } + if (max_length <= 0) max_length = -1; + if (type.StartsWith("_")) + { + type = type.Substring(1); + if (attndims == 0) attndims++; + } + if (sqlType.StartsWith("_")) sqlType = sqlType.Substring(1); + if (max_length > 0) + { + switch (sqlType.ToLower()) + { + //case "numeric": sqlType += $"({max_length})"; break; + case "bpchar": case "varchar": case "bytea": case "bit": case "varbit": sqlType += $"({max_length})"; break; + } + } + if (attndims > 0) type += "[]"; + + loc3[object_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[object_id], + Comment = comment, + DefaultValue = defaultValue, + Position = attnum + }); + loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); + loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); + } + + sql = $@" +select +ns.nspname || '.' || d.relname as table_id, +c.attname, +b.relname as index_id, +case when a.indisunique then 1 else 0 end IsUnique, +case when a.indisprimary then 1 else 0 end IsPrimary, +case when a.indisclustered then 0 else 1 end IsClustered, +{(is96 ? "case when pg_index_column_has_property(b.oid, c.attnum, 'desc') = 't' then 1 else 0 end" : "0")} IsDesc, +a.indkey::text, +c.attnum +from pg_index a +inner join pg_class b on b.oid = a.indexrelid +inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid +inner join pg_namespace ns on ns.oid = b.relnamespace +inner join pg_class d on d.oid = a.indrelid +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || d.relname")} +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); + foreach (object[] row in ds) + { + var object_id = string.Concat(row[0]); + var column = string.Concat(row[1]); + var index_id = string.Concat(row[2]); + var is_unique = string.Concat(row[3]) == "1"; + var is_primary_key = string.Concat(row[4]) == "1"; + var is_clustered = string.Concat(row[5]) == "1"; + var is_desc = string.Concat(row[6]) == "1"; + var inkey = string.Concat(row[7]).Split(' '); + var attnum = int.Parse(string.Concat(row[8])); + attnum = int.Parse(inkey[attnum - 1]); + //foreach (string tc in loc3[object_id].Keys) + //{ + // if (loc3[object_id][tc].DbTypeText.EndsWith("[]")) + // { + // column = tc; + // break; + // } + //} + if (loc3.ContainsKey(object_id) == false || loc3[object_id].ContainsKey(column) == false) continue; + var loc9 = loc3[object_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + + Dictionary loc10 = null; + DbIndexInfo loc11 = null; + if (!indexColumns.TryGetValue(object_id, out loc10)) + indexColumns.Add(object_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(object_id, out loc10)) + uniqueColumns.Add(object_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + } + } + foreach (var object_id in indexColumns.Keys) + { + foreach (var column in indexColumns[object_id]) + loc2[object_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (var object_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[object_id]) + { + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); + loc2[object_id].UniquesDict.Add(column.Key, column.Value); + } + } + + if (tbname == null) + { + sql = $@" +select +ns.nspname || '.' || b.relname as table_id, +array(select attname from pg_attribute where attrelid = a.conrelid and attnum = any(a.conkey)) as column_name, +a.conname as FKId, +ns2.nspname || '.' || c.relname as ref_table_id, +1 as IsForeignKey, +array(select attname from pg_attribute where attrelid = a.confrelid and attnum = any(a.confkey)) as ref_column, +null ref_sln, +null ref_table +from pg_constraint a +inner join pg_class b on b.oid = a.conrelid +inner join pg_class c on c.oid = a.confrelid +inner join pg_namespace ns on ns.oid = b.relnamespace +inner join pg_namespace ns2 on ns2.oid = c.relnamespace +where {loc8.ToString().Replace("a.table_name", "ns.nspname || '.' || b.relname")} +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var fkColumns = new Dictionary>(); + foreach (object[] row in ds) + { + var table_id = string.Concat(row[0]); + var column = row[1] as string[]; + var fk_id = string.Concat(row[2]); + var ref_table_id = string.Concat(row[3]); + var is_foreign_key = string.Concat(row[4]) == "1"; + var referenced_column = row[5] as string[]; + var referenced_db = string.Concat(row[6]); + var referenced_table = string.Concat(row[7]); + + if (loc2.ContainsKey(ref_table_id) == false) continue; + + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(table_id, out loc12)) + fkColumns.Add(table_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[table_id], ReferencedTable = loc2[ref_table_id] }); + + for (int a = 0; a < column.Length; a++) + { + loc13.Columns.Add(loc3[table_id][column[a]]); + loc13.ReferencedColumns.Add(loc3[ref_table_id][referenced_column[a]]); + } + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + } + + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); + + loc2.Clear(); + loc3.Clear(); + tables.AddRange(loc1); + } + return tables; + } + + public class GetEnumsByDatabaseQueryInfo + { + public string name { get; set; } + public string label { get; set; } + } + public List GetEnumsByDatabase(params string[] database) + { + if (database == null || database.Length == 0) return new List(); + var drs = _orm.Ado.Query(CommandType.Text, _commonUtils.FormatSql(@" +select +ns.nspname || '.' || a.typname AS name, +b.enumlabel AS label +from pg_type a +inner join pg_enum b on b.enumtypid = a.oid +inner join pg_namespace ns on ns.oid = a.typnamespace +where a.typtype = 'e' and ns.nspname in (SELECT ""schema_name"" FROM information_schema.schemata where catalog_name in {0})", database)); + var ret = new Dictionary>(); + foreach (var dr in drs) + { + if (ret.TryGetValue(dr.name, out var labels) == false) ret.Add(dr.name, labels = new Dictionary()); + var key = dr.label; + if (Regex.IsMatch(key, @"^[\u0391-\uFFE5a-zA-Z_\$][\u0391-\uFFE5a-zA-Z_\$\d]*$") == false) + key = $"Unkown{ret[dr.name].Count + 1}"; + if (labels.ContainsKey(key) == false) labels.Add(key, dr.label); + } + return ret.Select(a => new DbEnumInfo { Name = a.Key, Labels = a.Value }).ToList(); + } + + public static bool PgVersionIs96(string serverVersion) + { + int[] version = serverVersion.Split('.').Select(a => int.TryParse(a, out var tryint) ? tryint : 0).ToArray(); + if (version?.Any() != true) return true; + if (version[0] > 9) return true; + if (version[0] == 9 && version.Length > 1 && version[1] >= 6) return true; + return false; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLExpression.cs new file mode 100644 index 00000000..6b33a0eb --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLExpression.cs @@ -0,0 +1,658 @@ +using FreeSql.Internal; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Custom.PostgreSQL +{ + class CustomPostgreSQLExpression : CommonExpression + { + + public CustomPostgreSQLExpression(CommonUtils common) : base(common) { } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + var arrOperExp = getExp(arrOper); + if (arrOperExp.StartsWith("(") || arrOperExp.EndsWith(")")) return $"array_length(array[{arrOperExp.TrimStart('(').TrimEnd(')')}],1)"; + if (arrOper.Type == typeof(byte[])) return $"octet_length({getExp(arrOper)})"; + return $"case when {arrOperExp} is null then 0 else array_length({arrOperExp},1) end"; + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (exp.Type.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"(({getExp(operandExp)})::varchar not in ('0','false','f','no'))"; + case "System.Byte": return $"({getExp(operandExp)})::int2"; + case "System.Char": return $"substr(({getExp(operandExp)})::char, 1, 1)"; + case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"({getExp(operandExp)})::timestamp"; + case "System.Decimal": return $"({getExp(operandExp)})::numeric"; + case "System.Double": return $"({getExp(operandExp)})::float8"; + case "System.Int16": return $"({getExp(operandExp)})::int2"; + case "System.Int32": return $"({getExp(operandExp)})::int4"; + case "System.Int64": return $"({getExp(operandExp)})::int8"; + case "System.SByte": return $"({getExp(operandExp)})::int2"; + case "System.Single": return $"({getExp(operandExp)})::float4"; + case "System.String": return $"({getExp(operandExp)})::text"; + case "System.UInt16": return $"({getExp(operandExp)})::int2"; + case "System.UInt32": return $"({getExp(operandExp)})::int4"; + case "System.UInt64": return $"({getExp(operandExp)})::int8"; + case "System.Guid": return $"({getExp(operandExp)})::uuid"; + } + } + break; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"(({getExp(callExp.Arguments[0])})::varchar not in ('0','false','f','no'))"; + case "System.Byte": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Char": return $"substr(({getExp(callExp.Arguments[0])})::char, 1, 1)"; + case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"({getExp(callExp.Arguments[0])})::timestamp"; + case "System.Decimal": return $"({getExp(callExp.Arguments[0])})::numeric"; + case "System.Double": return $"({getExp(callExp.Arguments[0])})::float8"; + case "System.Int16": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Int32": return $"({getExp(callExp.Arguments[0])})::int4"; + case "System.Int64": return $"({getExp(callExp.Arguments[0])})::int8"; + case "System.SByte": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.Single": return $"({getExp(callExp.Arguments[0])})::float4"; + case "System.UInt16": return $"({getExp(callExp.Arguments[0])})::int2"; + case "System.UInt32": return $"({getExp(callExp.Arguments[0])})::int4"; + case "System.UInt64": return $"({getExp(callExp.Arguments[0])})::int8"; + case "System.Guid": return $"({getExp(callExp.Arguments[0])})::uuid"; + } + break; + case "NewGuid": + return null; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "(random()*1000000000)::int4"; + return null; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "random()"; + return null; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "random()"; + return null; + case "ToString": + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? $"({getExp(callExp.Object)})::text" : null; + return null; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substr({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArrayOrList()) + { + string left = null; + if (objType == typeof(Dictionary)) + { + left = objExp == null ? null : getExp(objExp); + switch (callExp.Method.Name) + { + case "get_Item": return $"{left}->{getExp(callExp.Arguments[argIndex])}"; + case "Contains": + var right = getExp(callExp.Arguments[argIndex]); + return $"({left} @> ({right}))"; + case "ContainsKey": return $"({left} ? {getExp(callExp.Arguments[argIndex])})"; + case "Concat": return $"({left} || {getExp(callExp.Arguments[argIndex])})"; + case "GetLength": + case "GetLongLength": + case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end"; + case "Keys": return $"akeys({left})"; + case "Values": return $"avals({left})"; + } + } + switch (callExp.Method.Name) + { + case "Any": + left = objExp == null ? null : getExp(objExp); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + return $"(case when {left} is null then 0 else array_length({left},1) end > 0)"; + case "Contains": + tsc.SetMapColumnTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = objExp?.NodeType == ExpressionType.MemberAccess ? tsc.SetDbParamsReturnOld(null) : null; //#900 UseGenerateCommandParameterWithLambda(true) 子查询 bug、以及 #1173 参数化 bug + tsc.isNotSetMapColumnTmp = true; + left = objExp == null ? null : getExp(objExp); + tsc.isNotSetMapColumnTmp = false; + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + if (oldDbParams != null) tsc.SetDbParamsReturnOld(oldDbParams); + //判断 in 或 array @> array + if (left.StartsWith("array[") || left.EndsWith("]")) + return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; + if (left.StartsWith("(") || left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; + args1 = $"array[{args1}]"; + if (objExp != null) + { + var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); + if (dbinfo != null) args1 = $"{args1}::{dbinfo.dbtype}"; + } + return $"({left} @> {args1})"; + case "Concat": + left = objExp == null ? null : getExp(objExp); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + var right2 = getExp(callExp.Arguments[argIndex]); + if (right2.StartsWith("(") || right2.EndsWith(")")) right2 = $"array[{right2.TrimStart('(').TrimEnd(')')}]"; + return $"({left} || {right2})"; + case "GetLength": + case "GetLongLength": + case "Length": + case "Count": + left = objExp == null ? null : getExp(objExp); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + return $"case when {left} is null then 0 else array_length({left},1) end"; + } + } + break; + case ExpressionType.MemberAccess: + var memExp = exp as MemberExpression; + var memParentExp = memExp.Expression?.Type; + if (memParentExp?.FullName == "System.Byte[]") return null; + if (memParentExp != null) + { + if (memParentExp.IsArray == true) + { + var left = getExp(memExp.Expression); + if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; + switch (memExp.Member.Name) + { + case "Length": + case "Count": return $"case when {left} is null then 0 else array_length({left},1) end"; + } + } + switch (memParentExp.FullName) + { + case "Newtonsoft.Json.Linq.JToken": + case "Newtonsoft.Json.Linq.JObject": + case "Newtonsoft.Json.Linq.JArray": + var left = getExp(memExp.Expression); + switch (memExp.Member.Name) + { + case "Count": return $"jsonb_array_length(coalesce({left},'[]'))"; + } + break; + } + if (memParentExp == typeof(Dictionary)) + { + var left = getExp(memExp.Expression); + switch (memExp.Member.Name) + { + case "Count": return $"case when {left} is null then 0 else array_length(akeys({left}),1) end"; + case "Keys": return $"akeys({left})"; + case "Values": return $"avals({left})"; + } + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("array["); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append("]").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"char_length({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; + case "Today": return "current_date"; + case "MinValue": return "'0001/1/1 0:00:00'::timestamp"; + case "MaxValue": return "'9999/12/31 23:59:59'::timestamp"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"({left})::date"; + case "TimeOfDay": return $"(extract(epoch from ({left})::time)*1000000)"; + case "DayOfWeek": return $"extract(dow from ({left})::timestamp)"; + case "Day": return $"extract(day from ({left})::timestamp)"; + case "DayOfYear": return $"extract(doy from ({left})::timestamp)"; + case "Month": return $"extract(month from ({left})::timestamp)"; + case "Year": return $"extract(year from ({left})::timestamp)"; + case "Hour": return $"extract(hour from ({left})::timestamp)"; + case "Minute": return $"extract(minute from ({left})::timestamp)"; + case "Second": return $"extract(second from ({left})::timestamp)"; + case "Millisecond": return $"(extract(milliseconds from ({left})::timestamp)-extract(second from ({left})::timestamp)*1000)"; + case "Ticks": return $"(extract(epoch from ({left})::timestamp)*10000000+621355968000000000)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 + case "MaxValue": return "922337203685477580"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"floor(({left})/{(long)1000000 * 60 * 60 * 24})"; + case "Hours": return $"floor(({left})/{(long)1000000 * 60 * 60}%24)"; + case "Milliseconds": return $"(floor(({left})/1000)::int8%1000)"; + case "Minutes": return $"(floor(({left})/{(long)1000000 * 60})::int8%60)"; + case "Seconds": return $"(floor(({left})/1000000)::int8%60)"; + case "Ticks": return $"(({left})*10)"; + case "TotalDays": return $"(({left})/{(long)1000000 * 60 * 60 * 24})"; + case "TotalHours": return $"(({left})/{(long)1000000 * 60 * 60})"; + case "TotalMilliseconds": return $"(({left})/1000)"; + case "TotalMinutes": return $"(({left})/{(long)1000000 * 60})"; + case "TotalSeconds": return $"(({left})/1000000)"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), null); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception(CoreStrings.Not_Implemented_Expression_ParameterUseConstant(exp,exp.Arguments[0])); + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => + { + var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis(); + if (atype == typeof(string)) return $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'"; + return $"'||{_common.IsNull($"({ExpressionLambdaToSql(a, tsc)})::text", "''")}||'"; + }).ToArray(); + return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs); + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(SqlExtExtensions).GetMethod("StringJoinPgsqlGroupConcat"), + Expression.Convert(toListArgs1.Body, typeof(object)), + Expression.Convert(exp.Arguments[0], typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + return newToListSql; + } + break; + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + if (args0Value.Contains("%")) + { + if (exp.Method.Name == "StartsWith") return $"strpos({args0Value}, {left}) = 1"; + if (exp.Method.Name == "EndsWith") return $"strpos({args0Value}, {left}) = char_length({args0Value})"; + return $"strpos({args0Value}, {left}) > 0"; + } + var likeOpt = "LIKE"; + if (exp.Arguments.Count > 1) + { + if (exp.Arguments[1].Type == typeof(bool) || + exp.Arguments[1].Type == typeof(StringComparison)) likeOpt = "ILIKE"; + } + if (exp.Method.Name == "StartsWith") return $"({left}) {likeOpt} {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(({args0Value})::text || '%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) {likeOpt} {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%' || ({args0Value})::text)")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) {likeOpt} {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) {likeOpt} ('%' || ({args0Value})::text || '%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"substr({left}, {substrArgs1})"; + return $"substr({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": return $"(strpos({left}, {getExp(exp.Arguments[0])})-1)"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": + case "TrimStart": + case "TrimEnd": + if (exp.Arguments.Count == 0) + { + if (exp.Method.Name == "Trim") return $"trim({left})"; + if (exp.Method.Name == "TrimStart") return $"ltrim({left})"; + if (exp.Method.Name == "TrimEnd") return $"rtrim({left})"; + } + var trimArg1 = ""; + var trimArg2 = ""; + foreach (var argsTrim02 in exp.Arguments) + { + var argsTrim01s = new[] { argsTrim02 }; + if (argsTrim02.NodeType == ExpressionType.NewArrayInit) + { + var arritem = argsTrim02 as NewArrayExpression; + argsTrim01s = arritem.Expressions.ToArray(); + } + foreach (var argsTrim01 in argsTrim01s) + { + var trimChr = getExp(argsTrim01).Trim('\''); + if (trimChr.Length == 1) trimArg1 += trimChr; + else trimArg2 += $" || ({trimChr})"; + } + } + if (exp.Method.Name == "Trim") left = $"trim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + if (exp.Method.Name == "TrimStart") left = $"ltrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + if (exp.Method.Name == "TrimEnd") left = $"rtrim({left}, {_common.FormatSql("{0}", trimArg1)}{trimArg2})"; + return left; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"case when {left} = {getExp(exp.Arguments[0])} then 0 when {left} > {getExp(exp.Arguments[0])} then 1 else -1 end"; + case "Equals": return $"({left} = ({getExp(exp.Arguments[0])})::text)"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])})"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": return $"log({getExp(exp.Arguments[0])})"; + case "Log10": return $"log10({getExp(exp.Arguments[0])})"; + case "Pow": return $"pow({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"trunc({getExp(exp.Arguments[0])}, 0)"; + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"extract(epoch from ({getExp(exp.Arguments[0])})::timestamp-({getExp(exp.Arguments[1])})::timestamp)"; + case "DaysInMonth": return $"extract(day from ({getExp(exp.Arguments[0])} || '-' || {getExp(exp.Arguments[1])} || '-01')::timestamp+'1 month'::interval-'1 day'::interval)"; + case "Equals": return $"(({getExp(exp.Arguments[0])})::timestamp = ({getExp(exp.Arguments[1])})::timestamp)"; + + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(({isLeapYearArgs1})::int8%4=0 AND ({isLeapYearArgs1})::int8%100<>0 OR ({isLeapYearArgs1})::int8%400=0)"; + + case "Parse": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"(({left})::timestamp+((({args1})/1000)||' milliseconds')::interval)"; + case "AddDays": return $"(({left})::timestamp+(({args1})||' day')::interval)"; + case "AddHours": return $"(({left})::timestamp+(({args1})||' hour')::interval)"; + case "AddMilliseconds": return $"(({left})::timestamp+(({args1})||' milliseconds')::interval)"; + case "AddMinutes": return $"(({left})::timestamp+(({args1})||' minute')::interval)"; + case "AddMonths": return $"(({left})::timestamp+(({args1})||' month')::interval)"; + case "AddSeconds": return $"(({left})::timestamp+(({args1})||' second')::interval)"; + case "AddTicks": return $"(({left})::timestamp+(({args1})/10||' microseconds')::interval)"; + case "AddYears": return $"(({left})::timestamp+(({args1})||' year')::interval)"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"(extract(epoch from ({left})::timestamp-({args1})::timestamp)*1000000)"; + case "System.TimeSpan": return $"(({left})::timestamp-((({args1})/1000)||' milliseconds')::interval)"; + } + break; + case "Equals": return $"({left} = ({args1})::timestamp)"; + case "CompareTo": return $"extract(epoch from ({left})::timestamp-({args1})::timestamp)"; + case "ToString": + if (left.EndsWith("::timestamp") == false) left = $"({left})::timestamp"; + if (exp.Arguments.Count == 0) return $"to_char({left},'YYYY-MM-DD HH24:MI:SS.US')"; + switch (args1) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"to_char({left},'YYYY-MM-DD HH24:MI:SS')"; + case "'yyyy-MM-dd HH:mm'": return $"to_char({left},'YYYY-MM-DD HH24:MI')"; + case "'yyyy-MM-dd HH'": return $"to_char({left},'YYYY-MM-DD HH24')"; + case "'yyyy-MM-dd'": return $"to_char({left},'YYYY-MM-DD')"; + case "'yyyy-MM'": return $"to_char({left},'YYYY-MM')"; + case "'yyyyMMddHHmmss'": return $"to_char({left},'YYYYMMDDHH24MISS')"; + case "'yyyyMMddHHmm'": return $"to_char({left},'YYYYMMDDHH24MI')"; + case "'yyyyMMddHH'": return $"to_char({left},'YYYYMMDDHH24')"; + case "'yyyyMMdd'": return $"to_char({left},'YYYYMMDD')"; + case "'yyyyMM'": return $"to_char({left},'YYYYMM')"; + case "'yyyy'": return $"to_char({left},'YYYY')"; + case "'HH:mm:ss'": return $"to_char({left},'HH24:MI:SS')"; + } + args1 = Regex.Replace(args1, "(yyyy|yy|MM|dd|HH|hh|mm|ss|tt)", m => + { + switch (m.Groups[1].Value) + { + case "yyyy": return $"YYYY"; + case "yy": return $"YY"; + case "MM": return $"%_a1"; + case "dd": return $"%_a2"; + case "HH": return $"%_a3"; + case "hh": return $"%_a4"; + case "mm": return $"%_a5"; + case "ss": return $"SS"; + case "tt": return $"%_a6"; + } + return m.Groups[0].Value; + }); + var argsFinds = new[] { "YYYY", "YY", "%_a1", "%_a2", "%_a3", "%_a4", "%_a5", "SS", "%_a6" }; + var argsSpts = Regex.Split(args1, "(M|d|H|h|m|s|t)"); + for (var a = 0; a < argsSpts.Length; a++) + { + switch (argsSpts[a]) + { + case "M": argsSpts[a] = $"ltrim(to_char({left},'MM'),'0')"; break; + case "d": argsSpts[a] = $"case when substr(to_char({left},'DD'),1,1) = '0' then substr(to_char({left},'DD'),2,1) else to_char({left},'DD') end"; break; + case "H": argsSpts[a] = $"case when substr(to_char({left},'HH24'),1,1) = '0' then substr(to_char({left},'HH24'),2,1) else to_char({left},'HH24') end"; break; + case "h": argsSpts[a] = $"case when substr(to_char({left},'HH12'),1,1) = '0' then substr(to_char({left},'HH12'),2,1) else to_char({left},'HH12') end"; break; + case "m": argsSpts[a] = $"case when substr(to_char({left},'MI'),1,1) = '0' then substr(to_char({left},'MI'),2,1) else to_char({left},'MI') end"; break; + case "s": argsSpts[a] = $"case when substr(to_char({left},'SS'),1,1) = '0' then substr(to_char({left},'SS'),2,1) else to_char({left},'SS') end"; break; + case "t": argsSpts[a] = $"rtrim(to_char({left},'AM'),'M')"; break; + default: + var argsSptsA = argsSpts[a]; + if (argsSptsA.StartsWith("'")) argsSptsA = argsSptsA.Substring(1); + if (argsSptsA.EndsWith("'")) argsSptsA = argsSptsA.Remove(argsSptsA.Length - 1); + argsSpts[a] = argsFinds.Any(m => argsSptsA.Contains(m)) ? $"to_char({left},'{argsSptsA}')" : $"'{argsSptsA}'"; + break; + } + } + if (argsSpts.Length > 0) args1 = $"({string.Join(" || ", argsSpts.Where(a => a != "''"))})"; + return args1.Replace("%_a1", "MM").Replace("%_a2", "DD").Replace("%_a3", "HH24").Replace("%_a4", "HH12").Replace("%_a5", "MI").Replace("%_a6", "AM"); + } + } + return null; + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60 * 24})"; + case "FromHours": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60 * 60})"; + case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})*1000)"; + case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*{(long)1000000 * 60})"; + case "FromSeconds": return $"(({getExp(exp.Arguments[0])})*1000000)"; + case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10)"; + case "Parse": return $"({getExp(exp.Arguments[0])})::int8"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"({getExp(exp.Arguments[0])})::int8"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left}-({args1}))"; + case "ToString": return $"({left})::varchar"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "ToBoolean": return $"(({getExp(exp.Arguments[0])})::varchar not in ('0','false','f','no'))"; + case "ToByte": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToChar": return $"substr(({getExp(exp.Arguments[0])})::char, 1, 1)"; + case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"({getExp(exp.Arguments[0])})::timestamp"; + case "ToDecimal": return $"({getExp(exp.Arguments[0])})::numeric"; + case "ToDouble": return $"({getExp(exp.Arguments[0])})::float8"; + case "ToInt16": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToInt32": return $"({getExp(exp.Arguments[0])})::int4"; + case "ToInt64": return $"({getExp(exp.Arguments[0])})::int8"; + case "ToSByte": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToSingle": return $"({getExp(exp.Arguments[0])})::float4"; + case "ToString": return $"({getExp(exp.Arguments[0])})::text"; + case "ToUInt16": return $"({getExp(exp.Arguments[0])})::int2"; + case "ToUInt32": return $"({getExp(exp.Arguments[0])})::int4"; + case "ToUInt64": return $"({getExp(exp.Arguments[0])})::int8"; + } + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLProvider.cs b/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLProvider.cs new file mode 100644 index 00000000..05cf72f9 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLProvider.cs @@ -0,0 +1,45 @@ +using FreeSql.Internal.CommonProvider; +using System; +using System.Data.Common; +using System.Threading; + +namespace FreeSql.Custom.PostgreSQL +{ + + public class CustomPostgreSQLProvider : BaseDbProvider, IFreeSql + { + public override ISelect CreateSelectProvider(object dywhere) => new CustomPostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new CustomPostgreSQLInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new CustomPostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new CustomPostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new CustomPostgreSQLInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); + + public CustomPostgreSQLProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) + { + this.InternalCommonUtils = new CustomPostgreSQLUtils(this); + this.InternalCommonExpression = new CustomPostgreSQLExpression(this.InternalCommonUtils); + + this.Ado = new CustomPostgreSQLAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); + this.Aop = new AopProvider(); + + this.DbFirst = new CustomPostgreSQLDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new CustomPostgreSQLCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + } + + ~CustomPostgreSQLProvider() => this.Dispose(); + int _disposeCounter; + public override void Dispose() + { + if (Interlocked.Increment(ref _disposeCounter) != 1) return; + try + { + (this.Ado as AdoProvider)?.Dispose(); + } + finally + { + FreeSqlCustomAdapterGlobalExtensions._dicCustomAdater.TryRemove(Ado.Identifier, out var tryada); + FreeSqlCustomAdapterGlobalExtensions._dicDbProviderFactory.TryRemove(Ado.Identifier, out var trydbpf); + } + } + } +} diff --git a/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLUtils.cs b/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLUtils.cs new file mode 100644 index 00000000..7e83cfa8 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLUtils.cs @@ -0,0 +1,168 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Globalization; +using System.Linq; +using System.Text; + +namespace FreeSql.Custom.PostgreSQL +{ + + class CustomPostgreSQLUtils : CommonUtils + { + DbProviderFactory Factory => FreeSqlCustomAdapterGlobalExtensions.GetDbProviderFactory(_orm); + + public CustomPostgreSQLUtils(IFreeSql orm) : base(orm) + { + } + + static Array getParamterArrayValue(Type arrayType, object value, object defaultValue) + { + var valueArr = value as Array; + var len = valueArr.GetLength(0); + var ret = Array.CreateInstance(arrayType, len); + for (var a = 0; a < len; a++) + { + var item = valueArr.GetValue(a); + ret.SetValue(item == null ? defaultValue : getParamterValue(item.GetType(), item, 1), a); + } + return ret; + } + static Dictionary> dicGetParamterValue = new Dictionary> { + { typeof(uint).FullName, a => long.Parse(string.Concat(a)) }, { typeof(uint[]).FullName, a => getParamterArrayValue(typeof(long), a, 0) }, { typeof(uint?[]).FullName, a => getParamterArrayValue(typeof(long?), a, null) }, + { typeof(ulong).FullName, a => decimal.Parse(string.Concat(a)) }, { typeof(ulong[]).FullName, a => getParamterArrayValue(typeof(decimal), a, 0) }, { typeof(ulong?[]).FullName, a => getParamterArrayValue(typeof(decimal?), a, null) }, + { typeof(ushort).FullName, a => int.Parse(string.Concat(a)) }, { typeof(ushort[]).FullName, a => getParamterArrayValue(typeof(int), a, 0) }, { typeof(ushort?[]).FullName, a => getParamterArrayValue(typeof(int?), a, null) }, + { typeof(byte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(byte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(byte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + { typeof(sbyte).FullName, a => short.Parse(string.Concat(a)) }, { typeof(sbyte[]).FullName, a => getParamterArrayValue(typeof(short), a, 0) }, { typeof(sbyte?[]).FullName, a => getParamterArrayValue(typeof(short?), a, null) }, + { typeof(char).FullName, a => string.Concat(a).Replace('\0', ' ').ToCharArray().FirstOrDefault() }, + }; + static object getParamterValue(Type type, object value, int level = 0) + { + if (type.FullName == "System.Byte[]") return value; + if (type.IsArray && level == 0) + { + var elementType = type.GetElementType(); + Type enumType = null; + if (elementType.IsEnum) enumType = elementType; + else if (elementType.IsNullableType()) + { + var genericTypesFirst = elementType.GetGenericArguments().First(); + if (genericTypesFirst.IsEnum) enumType = genericTypesFirst; + } + if (enumType != null) return enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + getParamterArrayValue(typeof(long), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue()) : + getParamterArrayValue(typeof(int), value, elementType.IsEnum ? null : enumType.CreateInstanceGetDefaultValue()); + return dicGetParamterValue.TryGetValue(type.FullName, out var trydicarr) ? trydicarr(value) : value; + } + if (type.IsNullableType()) type = type.GetGenericArguments().First(); + if (type.IsEnum) return (int)value; + if (dicGetParamterValue.TryGetValue(type.FullName, out var trydic)) return trydic(value); + return value; + } + + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (value != null) value = getParamterValue(type, value); + var ret = Factory.CreateParameter(); + ret.ParameterName = QuoteParamterName(parameterName); + ret.Value = value; + //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { + // ret.DataTypeName = ""; + //} else { + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.DbType = (DbType)tp.Value; + //} + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => + { + if (value != null) value = getParamterValue(type, value); + var ret = Factory.CreateParameter(); + ret.ParameterName = $"@{name}"; + ret.Value = value; + //if (value.GetType().IsEnum || value.GetType().GenericTypeArguments.FirstOrDefault()?.IsEnum == true) { + // ret.DataTypeName = ""; + //} else { + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.DbType = (DbType)tp.Value; + //} + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatCustomPostgreSQL(args); + public override string QuoteSqlName(params string[] name) + { + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("\"") && nametrim.EndsWith("\"")) + return nametrim; + return $"\"{nametrim.Replace(".", "\".\"")}\""; + } + return $"\"{string.Join("\".\"", name)}\""; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.Trim('"').Replace("\".\"", ".").Replace(".\"", ".")}"; + } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '"', '"', 2); + public override string QuoteParamterName(string name) => $"@{(name.ToLower())}"; + public override string IsNull(string sql, object value) => $"coalesce({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) => $"{string.Join(" || ", objs)}"; + public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; + public override string Now => "current_timestamp"; + public override string NowUtc => "(current_timestamp at time zone 'UTC')"; + + public override string QuoteWriteParamterAdapter(Type type, string paramterName) => paramterName; + protected override string QuoteReadColumnAdapter(Type type, Type mapType, string columnName) => columnName; + + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) + { + if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); + value = getParamterValue(type, value); + var type2 = value.GetType(); + if (type2 == typeof(byte[])) return $"'\\x{CommonUtils.BytesSqlRaw(value as byte[])}'"; + if (type2 == typeof(TimeSpan) || type2 == typeof(TimeSpan?)) + { + var ts = (TimeSpan)value; + return $"'{Math.Min(24, (int)Math.Floor(ts.TotalHours))}:{ts.Minutes}:{ts.Seconds}'"; + } + else if (value is Array) + { + var valueArr = value as Array; + var eleType = type2.GetElementType(); + var len = valueArr.GetLength(0); + var sb = new StringBuilder().Append("ARRAY["); + for (var a = 0; a < len; a++) + { + var item = valueArr.GetValue(a); + if (a > 0) sb.Append(","); + sb.Append(GetNoneParamaterSqlValue(specialParams, specialParamFlag, col, eleType, item)); + } + sb.Append("]"); + var dbinfo = _orm.CodeFirst.GetDbInfo(type); + if (dbinfo != null) sb.Append("::").Append(dbinfo.dbtype); + return sb.ToString(); + } + else if (dicGetParamterValue.ContainsKey(type2.FullName)) + { + value = string.Concat(value); + } + return FormatSql("{0}", value, 1); + } + } +} diff --git a/Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerDelete.cs b/Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerDelete.cs new file mode 100644 index 00000000..939a20ae --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerDelete.cs @@ -0,0 +1,133 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Custom.SqlServer +{ + + class CustomSqlServerDelete : Internal.CommonProvider.DeleteProvider + { + public CustomSqlServerDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override List ExecuteDeleted() + { + var ret = new List(); + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => + { + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" OUTPUT "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, $"DELETED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.ToString(); + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException(CoreStrings.S_NotFound_Name("WHERE")); + sql = sb.Clear().Append(sql.Substring(0, validx)) + .Append(sbret) + .Append(sql.Substring(validx)).ToString(); + + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(_orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) + { + this.ClearData(); + sbret.Clear(); + } + return ret; + } + +#if net40 +#else + async public override Task> ExecuteDeletedAsync(CancellationToken cancellationToken = default) + { + var ret = new List(); + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => + { + if (dbParms == null) + { + dbParms = _params.ToArray(); + sbret = new StringBuilder(); + sbret.Append(" OUTPUT "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, $"DELETED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.ToString(); + var validx = sql.IndexOf(" WHERE "); + if (validx == -1) throw new ArgumentException(CoreStrings.S_NotFound_Name("WHERE")); + sql = sb.Clear().Append(sql.Substring(0, validx)) + .Append(sbret) + .Append(sql.Substring(validx)).ToString(); + + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Delete, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + ret.AddRange(await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken)); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + if (dbParms != null) + { + this.ClearData(); + sbret.Clear(); + } + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerInsert.cs b/Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerInsert.cs new file mode 100644 index 00000000..65d84689 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerInsert.cs @@ -0,0 +1,191 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Custom.SqlServer +{ + + class CustomSqlServerInsert : Internal.CommonProvider.InsertProvider where T1 : class + { + public CustomSqlServerInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override List ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + + public override string ToSql() + { + var versionGreaterThan10 = (_commonUtils as CustomSqlServerUtils).ServerVersion > 10; + return this.ToSqlValuesOrSelectUnionAll(versionGreaterThan10); + } + protected override long RawExecuteIdentity() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + protected override List RawExecuteInserted() + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.RereadColumn(col, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + + if ((_commonUtils as CustomSqlServerUtils).ServerVersion > 10) + { + var validx = sql.IndexOf(") VALUES"); + if (validx == -1) throw new ArgumentException(CoreStrings.S_NotFound_Name("VALUES")); + sb.Insert(0, sql.Substring(0, validx + 1)); + sb.Append(sql.Substring(validx + 1)); + } + else + { + var validx = sql.IndexOf(") SELECT "); + if (validx == -1) throw new ArgumentException(CoreStrings.S_NotFound_Name("SELECT")); + sb.Insert(0, sql.Substring(0, validx + 1)); + sb.Append(sql.Substring(validx + 1)); + } + + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100, cancellationToken); + public override Task ExecuteIdentityAsync(CancellationToken cancellationToken = default) => base.SplitExecuteIdentityAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100, cancellationToken); + public override Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteInsertedAsync(_batchValuesLimit > 0 ? _batchValuesLimit : 1000, _batchParameterLimit > 0 ? _batchParameterLimit : 2100, cancellationToken); + + async protected override Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default) + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return 0; + + sql = string.Concat(sql, "; SELECT SCOPE_IDENTITY();"); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + long ret = 0; + Exception exception = null; + try + { + long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken)), out ret); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } + async protected override Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default) + { + var sql = this.ToSql(); + if (string.IsNullOrEmpty(sql)) return new List(); + + var sb = new StringBuilder(); + sb.Append(" OUTPUT "); + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.RereadColumn(col, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + + if ((_commonUtils as CustomSqlServerUtils).ServerVersion > 10) + { + var validx = sql.IndexOf(") VALUES"); + if (validx == -1) throw new ArgumentException(CoreStrings.S_NotFound_Name("VALUES")); + sb.Insert(0, sql.Substring(0, validx + 1)); + sb.Append(sql.Substring(validx + 1)); + } + else + { + var validx = sql.IndexOf(") SELECT "); + if (validx == -1) throw new ArgumentException(CoreStrings.S_NotFound_Name("SELECT")); + sb.Insert(0, sql.Substring(0, validx + 1)); + sb.Append(sql.Substring(validx + 1)); + } + + sql = sb.ToString(); + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var ret = new List(); + Exception exception = null; + try + { + ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + return ret; + } +#endif + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerInsertOrUpdate.cs b/Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerInsertOrUpdate.cs new file mode 100644 index 00000000..2d8ea831 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerInsertOrUpdate.cs @@ -0,0 +1,78 @@ +using FreeSql.Internal; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Text; + +namespace FreeSql.Custom.SqlServer +{ + + class CustomSqlServerInsertOrUpdate : Internal.CommonProvider.InsertOrUpdateProvider where T1 : class + { + public CustomSqlServerInsertOrUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + : base(orm, commonUtils, commonExpression) + { + } + + public override string ToSql() + { + var dbParams = new List(); + if (_sourceSql != null) return getMergeSql(null); + if (_source?.Any() != true) return null; + + var sqls = new string[2]; + var ds = SplitSourceByIdentityValueIsNull(_source); + if (ds.Item1.Any()) sqls[0] = string.Join("\r\n\r\n;\r\n\r\n", ds.Item1.Select(a => getMergeSql(a))); + if (ds.Item2.Any()) sqls[1] = string.Join("\r\n\r\n;\r\n\r\n", ds.Item2.Select(a => getInsertSql(a))); + _params = dbParams.ToArray(); + if (ds.Item2.Any() == false) return sqls[0]; + if (ds.Item1.Any() == false) return sqls[1]; + return string.Join("\r\n\r\n;\r\n\r\n", sqls); + + string getMergeSql(List data) + { + if (_tempPrimarys.Any() == false) throw new Exception(CoreStrings.InsertOrUpdate_Must_Primary_Key(_table.CsName)); + + var sb = new StringBuilder(); + if (IdentityColumn != null) sb.Append("SET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" ON;\r\n"); + sb.Append("MERGE INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" t1 \r\nUSING ("); + WriteSourceSelectUnionAll(data, sb, dbParams); + sb.Append(" ) t2 ON (").Append(string.Join(" AND ", _tempPrimarys.Select(a => $"t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(") \r\n"); + + var cols = _table.Columns.Values.Where(a => _tempPrimarys.Contains(a) == false && a.Attribute.CanUpdate == true && _updateIgnore.ContainsKey(a.Attribute.Name) == false); + if (_doNothing == false && cols.Any()) + sb.Append("WHEN MATCHED THEN \r\n") + .Append(" update set ").Append(string.Join(", ", cols.Select(a => + a.Attribute.IsVersion && a.Attribute.MapType != typeof(byte[]) ? + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t1.{_commonUtils.QuoteSqlName(a.Attribute.Name)} + 1" : + $"{_commonUtils.QuoteSqlName(a.Attribute.Name)} = t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}" + ))).Append(" \r\n"); + + cols = _table.Columns.Values.Where(a => a.Attribute.CanInsert == true); + if (cols.Any()) + sb.Append("WHEN NOT MATCHED THEN \r\n") + .Append(" insert (").Append(string.Join(", ", cols.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(") \r\n") + .Append(" values (").Append(string.Join(", ", cols.Select(a => $"t2.{_commonUtils.QuoteSqlName(a.Attribute.Name)}"))).Append(");"); + + if (IdentityColumn != null) sb.Append(";\r\nSET IDENTITY_INSERT ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" OFF;"); + + return sb.ToString(); + } + string getInsertSql(List data) + { + var insert = _orm.Insert() + .AsTable(_tableRule).AsType(_table.Type) + .WithConnection(_connection) + .WithTransaction(_transaction) + .NoneParameter(true) as Internal.CommonProvider.InsertProvider; + insert._source = data; + insert._table = _table; + var sql = insert.ToSql(); + if (string.IsNullOrEmpty(sql)) return null; + if (insert._params?.Any() == true) dbParams.AddRange(insert._params); + return sql; + } + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerSelect.cs b/Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerSelect.cs new file mode 100644 index 00000000..bc4bf5ed --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerSelect.cs @@ -0,0 +1,369 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql.Custom.SqlServer +{ + + class CustomSqlServerSelect : FreeSql.Internal.CommonProvider.Select1Provider + { + + internal static string ToSqlStatic(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) + => (_commonUtils as CustomSqlServerUtils).IsSelectRowNumber ? + ToSqlStaticRowNumber(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm) : + ToSqlStaticOffsetFetchNext(_commonUtils, _commonExpression, _select, _distinct, field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, tbUnions, _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + + #region SqlServer 2005 row_number + internal static string ToSqlStaticRowNumber(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereGlobalFilter.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append(" \r\n\r\nUNION ALL\r\n\r\n"); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + //if (_limit > 0) sb.Append("TOP ").Append(_skip + _limit).Append(" "); //TOP 会引发 __rownum__ 无序的问题 + if (_skip <= 0 && _limit > 0) sb.Append("TOP ").Append(_limit).Append(" "); + sb.Append(field); + + if (_limit > 0 || _skip > 0) + { + if (string.IsNullOrEmpty(_orderby)) + { + if (string.IsNullOrEmpty(_groupby)) + { + var pktb = _tables.Where(a => a.Table.Primarys.Any()).FirstOrDefault(); + if (pktb != null) _orderby = string.Concat(" \r\nORDER BY ", pktb.Alias, ".", _commonUtils.QuoteSqlName(pktb?.Table.Primarys.First().Attribute.Name)); + else _orderby = string.Concat(" \r\nORDER BY ", _tables.First().Alias, ".", _commonUtils.QuoteSqlName(_tables.First().Table.Columns.First().Value.Attribute.Name)); + } + else + _orderby = _groupby.Replace("GROUP BY ", "ORDER BY "); + } + if (_skip > 0) // 注意这个判断,大于 0 才使用 ROW_NUMBER ,否则属于第一页直接使用 TOP + sb.Append(", ROW_NUMBER() OVER(").Append(_orderby.Trim('\r', '\n', ' ')).Append(") AS __rownum__"); + } + sb.Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); + } + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + switch (tb.Type) + { + case SelectTableInfoType.Parent: + case SelectTableInfoType.RawJoin: + continue; + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND ").Append(_tables[0].Cascade); + + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + if (_skip <= 0) + sb.Append(_orderby); + else + { + sb.Insert(0, "WITH t AS ( ").Append(" ) SELECT t.* FROM t where __rownum__"); + if (_limit > 0) + sb.Append(" between ").Append(_skip + 1).Append(" and ").Append(_skip + _limit); + else + sb.Append(" > ").Append(_skip); + } + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.Append(_tosqlAppendContent).ToString(); + } + #endregion + + #region SqlServer 2012+ offset feach next + internal static string ToSqlStaticOffsetFetchNext(CommonUtils _commonUtils, CommonExpression _commonExpression, string _select, bool _distinct, string field, StringBuilder _join, StringBuilder _where, string _groupby, string _having, string _orderby, int _skip, int _limit, List _tables, List> tbUnions, Func _aliasRule, string _tosqlAppendContent, List _whereGlobalFilter, IFreeSql _orm) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + _orm.CodeFirst.SyncStructure(_tables.Select(a => a.Table.Type).ToArray()); + + if (_whereGlobalFilter.Any()) + foreach (var tb in _tables.Where(a => a.Type != SelectTableInfoType.Parent)) + tb.Cascade = _commonExpression.GetWhereCascadeSql(tb, _whereGlobalFilter, true); + + var sb = new StringBuilder(); + var tbUnionsGt0 = tbUnions.Count > 1; + for (var tbUnionsIdx = 0; tbUnionsIdx < tbUnions.Count; tbUnionsIdx++) + { + if (tbUnionsIdx > 0) sb.Append("\r\n \r\nUNION ALL\r\n \r\n"); + if (tbUnionsGt0) sb.Append(_select).Append(" * from ("); + var tbUnion = tbUnions[tbUnionsIdx]; + + var sbnav = new StringBuilder(); + sb.Append(_select); + if (_distinct) sb.Append("DISTINCT "); + if (_skip <= 0 && _limit > 0) sb.Append("TOP ").Append(_limit).Append(" "); + sb.Append(field); + sb.Append(" \r\nFROM "); + var tbsjoin = _tables.Where(a => a.Type != SelectTableInfoType.From).ToArray(); + var tbsfrom = _tables.Where(a => a.Type == SelectTableInfoType.From).ToArray(); + for (var a = 0; a < tbsfrom.Length; a++) + { + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[a].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[a].Table.Type, tbsfrom[a].Alias) ?? tbsfrom[a].Alias); + if (tbsjoin.Length > 0) + { + //如果存在 join 查询,则处理 from t1, t2 改为 from t1 inner join t2 on 1 = 1 + for (var b = 1; b < tbsfrom.Length; b++) + { + sb.Append(" \r\nLEFT JOIN ").Append(_commonUtils.QuoteSqlName(tbUnion[tbsfrom[b].Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tbsfrom[b].Table.Type, tbsfrom[b].Alias) ?? tbsfrom[b].Alias); + + if (string.IsNullOrEmpty(tbsfrom[b].NavigateCondition) && string.IsNullOrEmpty(tbsfrom[b].On) && string.IsNullOrEmpty(tbsfrom[b].Cascade)) sb.Append(" ON 1 = 1"); + else + { + var onSql = tbsfrom[b].NavigateCondition ?? tbsfrom[b].On; + sb.Append(" ON ").Append(onSql); + if (string.IsNullOrEmpty(tbsfrom[b].Cascade) == false) + { + if (string.IsNullOrEmpty(onSql)) sb.Append(tbsfrom[b].Cascade); + else sb.Append(" AND ").Append(tbsfrom[b].Cascade); + } + } + } + break; + } + else + { + if (!string.IsNullOrEmpty(tbsfrom[a].NavigateCondition)) sbnav.Append(" AND (").Append(tbsfrom[a].NavigateCondition).Append(")"); + if (!string.IsNullOrEmpty(tbsfrom[a].On)) sbnav.Append(" AND (").Append(tbsfrom[a].On).Append(")"); + if (a > 0 && !string.IsNullOrEmpty(tbsfrom[a].Cascade)) sbnav.Append(" AND ").Append(tbsfrom[a].Cascade); + } + if (a < tbsfrom.Length - 1) sb.Append(", "); + } + foreach (var tb in tbsjoin) + { + switch (tb.Type) + { + case SelectTableInfoType.Parent: + case SelectTableInfoType.RawJoin: + continue; + case SelectTableInfoType.LeftJoin: + sb.Append(" \r\nLEFT JOIN "); + break; + case SelectTableInfoType.InnerJoin: + sb.Append(" \r\nINNER JOIN "); + break; + case SelectTableInfoType.RightJoin: + sb.Append(" \r\nRIGHT JOIN "); + break; + } + sb.Append(_commonUtils.QuoteSqlName(tbUnion[tb.Table.Type])).Append(" ").Append(_aliasRule?.Invoke(tb.Table.Type, tb.Alias) ?? tb.Alias).Append(" ON ").Append(tb.On ?? tb.NavigateCondition); + if (!string.IsNullOrEmpty(tb.Cascade)) sb.Append(" AND ").Append(tb.Cascade); + if (!string.IsNullOrEmpty(tb.On) && !string.IsNullOrEmpty(tb.NavigateCondition)) sbnav.Append(" AND (").Append(tb.NavigateCondition).Append(")"); + } + if (_join.Length > 0) sb.Append(_join); + + sbnav.Append(_where); + if (!string.IsNullOrEmpty(_tables[0].Cascade)) + sbnav.Append(" AND ").Append(_tables[0].Cascade); + + if (sbnav.Length > 0) + { + sb.Append(" \r\nWHERE ").Append(sbnav.Remove(0, 5)); + } + if (string.IsNullOrEmpty(_groupby) == false) + { + sb.Append(_groupby); + if (string.IsNullOrEmpty(_having) == false) + sb.Append(" \r\nHAVING ").Append(_having.Substring(5)); + } + if (_skip > 0) + { + if (string.IsNullOrEmpty(_orderby)) + { + if (string.IsNullOrEmpty(_groupby)) + { + var pktb = _tables.Where(a => a.Table.Primarys.Any()).FirstOrDefault(); + if (pktb != null) _orderby = string.Concat(" \r\nORDER BY ", pktb.Alias, ".", _commonUtils.QuoteSqlName(pktb?.Table.Primarys.First().Attribute.Name)); + else _orderby = string.Concat(" \r\nORDER BY ", _tables.First().Alias, ".", _commonUtils.QuoteSqlName(_tables.First().Table.Columns.First().Value.Attribute.Name)); + } + else + _orderby = _groupby.Replace("GROUP BY ", "ORDER BY "); + } + sb.Append(_orderby).Append($" \r\nOFFSET {_skip} ROW"); + if (_limit > 0) sb.Append($" \r\nFETCH NEXT {_limit} ROW ONLY"); + } + else + { + sb.Append(_orderby); + } + + sbnav.Clear(); + if (tbUnionsGt0) sb.Append(") ftb"); + } + return sb.Append(_tosqlAppendContent).ToString(); + } + #endregion + + public CustomSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override ISelect From(Expression, T2, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); CustomSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); CustomSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); CustomSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); CustomSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); CustomSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); CustomSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); CustomSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); CustomSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); CustomSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); CustomSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); CustomSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); CustomSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); CustomSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); CustomSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) { this.InternalFrom(exp); var ret = new OdbcSqlServerSelect(_orm, _commonUtils, _commonExpression, null); CustomSqlServerSelect.CopyData(this, ret, exp?.Parameters); return ret; } + public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select2Provider where T2 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select3Provider where T2 : class where T3 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select4Provider where T2 : class where T3 : class where T4 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select5Provider where T2 : class where T3 : class where T4 : class where T5 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select6Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select7Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select8Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select9Provider where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select10Provider 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 + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select11Provider 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 where T11 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select12Provider 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 where T11 : class where T12 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select13Provider 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 where T11 : class where T12 : class where T13 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select14Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select15Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } + class OdbcSqlServerSelect : FreeSql.Internal.CommonProvider.Select16Provider 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class + { + public OdbcSqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { } + public override string ToSql(string field = null) => CustomSqlServerSelect.ToSqlStatic(_commonUtils, _commonExpression, _select, _distinct, field ?? this.GetAllFieldExpressionTreeLevel2().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, this.GetTableRuleUnions(), _aliasRule, _tosqlAppendContent, _whereGlobalFilter, _orm); + } +} diff --git a/Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerUpdate.cs b/Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerUpdate.cs new file mode 100644 index 00000000..567dcf72 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/SqlServer/Curd/CustomSqlServerUpdate.cs @@ -0,0 +1,173 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Custom.SqlServer +{ + + class CustomSqlServerUpdate : Internal.CommonProvider.UpdateProvider + { + + public CustomSqlServerUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) + : base(orm, commonUtils, commonExpression, dywhere) + { + } + + public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + public override List ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100); + + protected override List RawExecuteUpdated() + { + var ret = new List(); + DbParameter[] dbParms = null; + StringBuilder sbret = null; + ToSqlFetch(sb => + { + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" OUTPUT "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.ToString(); + var validx = sql.IndexOf(" \r\nWHERE "); + if (validx == -1) throw new ArgumentException(CoreStrings.S_NotFound_Name("WHERE")); + sql = sb.Clear().Append(sql.Substring(0, validx)) + .Append(sbret) + .Append(sql.Substring(validx)).ToString(); + + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); + return ret; + } + + protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) + { + if (primarys.Length == 1) + { + var pk = primarys.First(); + caseWhen.Append(_commonUtils.RereadColumn(pk, _commonUtils.QuoteSqlName(pk.Attribute.Name))); + return; + } + caseWhen.Append("("); + var pkidx = 0; + foreach (var pk in primarys) + { + if (pkidx > 0) caseWhen.Append(" + '+' + "); + caseWhen.Append("cast(").Append(_commonUtils.RereadColumn(pk, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append(" as varchar)"); + ++pkidx; + } + caseWhen.Append(")"); + } + + protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) + { + if (primarys.Length == 1) + { + sb.Append(_commonUtils.FormatSql("{0}", primarys[0].GetDbValue(d))); + return; + } + var pkidx = 0; + foreach (var pk in primarys) + { + if (pkidx > 0) sb.Append(" + '+' + "); + sb.Append("cast(").Append(_commonUtils.FormatSql("{0}", pk.GetDbValue(d))).Append(" as varchar)"); + ++pkidx; + } + } + +#if net40 +#else + public override Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100, cancellationToken); + public override Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 2100, cancellationToken); + + async protected override Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) + { + var ret = new List(); + DbParameter[] dbParms = null; + StringBuilder sbret = null; + await ToSqlFetchAsync(async sb => + { + if (dbParms == null) + { + dbParms = _params.Concat(_paramsSource).ToArray(); + sbret = new StringBuilder(); + sbret.Append(" OUTPUT "); + + var colidx = 0; + foreach (var col in _table.Columns.Values) + { + if (colidx > 0) sbret.Append(", "); + sbret.Append(_commonUtils.RereadColumn(col, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); + ++colidx; + } + } + var sql = sb.ToString(); + var validx = sql.IndexOf(" \r\nWHERE "); + if (validx == -1) throw new ArgumentException(CoreStrings.S_NotFound_Name("WHERE")); + sql = sb.Clear().Append(sql.Substring(0, validx)) + .Append(sbret) + .Append(sql.Substring(validx)).ToString(); + + var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Update, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + + Exception exception = null; + try + { + var rettmp = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + ValidateVersionAndThrow(rettmp.Count, sql, dbParms); + ret.AddRange(rettmp); + } + catch (Exception ex) + { + exception = ex; + throw ex; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + }); + sbret?.Clear(); + return ret; + } +#endif + } +} diff --git a/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerAdo/CustomSqlServerAdo.cs b/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerAdo/CustomSqlServerAdo.cs new file mode 100644 index 00000000..caee63af --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerAdo/CustomSqlServerAdo.cs @@ -0,0 +1,83 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using FreeSql.Internal.ObjectPool; +using System; +using System.Collections; +using System.Data.Common; +using System.Linq; +using System.Text; +using System.Threading; + +namespace FreeSql.Custom.SqlServer +{ + class CustomSqlServerAdo : FreeSql.Internal.CommonProvider.AdoProvider + { + DbProviderFactory Factory => FreeSqlCustomAdapterGlobalExtensions.GetDbProviderFactory(_util._orm); + + public CustomSqlServerAdo() : base(DataType.OdbcSqlServer, null, null) { } + public CustomSqlServerAdo(CommonUtils util, string masterConnectionString, string[] slaveConnectionStrings, Func connectionFactory) : base(DataType.OdbcSqlServer, masterConnectionString, slaveConnectionStrings) + { + base._util = util; + if (connectionFactory != null) + { + var pool = new FreeSql.Internal.CommonProvider.DbConnectionPool(DataType.SqlServer, connectionFactory); + MasterPool = pool; + return; + } + throw new Exception(CoreStrings.S_CustomAdapter_OnlySuppport_UseConnectionFactory); + } + + string[] ncharDbTypes = new[] { "NVARCHAR", "NCHAR", "NTEXT" }; + public override object AddslashesProcessParam(object param, Type mapType, ColumnInfo mapColumn) + { + if (param == null) return "NULL"; + if (mapType != null && mapType != param.GetType() && (param is IEnumerable == false)) + param = Utils.GetDataReaderValue(mapType, param); + + if (param is bool || param is bool?) + return (bool)param ? 1 : 0; + else if (param is string) + { + if (mapColumn != null && mapColumn.CsType.NullableTypeOrThis() == typeof(string) && ncharDbTypes.Any(a => mapColumn.Attribute.DbType.Contains(a)) == false) + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + return string.Concat("N'", param.ToString().Replace("'", "''"), "'"); + } + else if (param is char) + return string.Concat("'", param.ToString().Replace("'", "''").Replace('\0', ' '), "'"); + else if (param is Enum) + return ((Enum)param).ToInt64(); + else if (decimal.TryParse(string.Concat(param), out var trydec)) + return param; + else if (param is DateTime || param is DateTime?) + { + if (param.Equals(DateTime.MinValue) == true) param = new DateTime(1970, 1, 1); + return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.fff"), "'"); + } + else if (param is DateTimeOffset || param is DateTimeOffset?) + { + if (param.Equals(DateTimeOffset.MinValue) == true) param = new DateTimeOffset(new DateTime(1970, 1, 1), TimeSpan.Zero); + return string.Concat("'", ((DateTimeOffset)param).ToString("yyyy-MM-dd HH:mm:ss.fff zzzz"), "'"); + } + else if (param is TimeSpan || param is TimeSpan?) + return ((TimeSpan)param).TotalSeconds; + else if (param is byte[]) + return $"0x{CommonUtils.BytesSqlRaw(param as byte[])}"; + else if (param is IEnumerable) + return AddslashesIEnumerable(param, mapType, mapColumn); + + return string.Concat("'", param.ToString().Replace("'", "''"), "'"); + } + + public override DbCommand CreateCommand() + { + return Factory.CreateCommand(); + } + + public override void ReturnConnection(IObjectPool pool, Object conn, Exception ex) + { + pool.Return(conn); + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerCodeFirst.cs new file mode 100644 index 00000000..96513be2 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerCodeFirst.cs @@ -0,0 +1,499 @@ +using FreeSql.Internal; +using FreeSql.Internal.Model; +using FreeSql.Internal.ObjectPool; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Linq; +using System.Text; + +namespace FreeSql.Custom.SqlServer +{ + + class CustomSqlServerCodeFirst : Internal.CommonProvider.CodeFirstProvider + { + public override bool IsNoneCommandParameter { get => true; set => base.IsNoneCommandParameter = true; } + public CustomSqlServerCodeFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) : base(orm, commonUtils, commonExpression) { } + + static object _dicCsToDbLock = new object(); + static Dictionary> _dicCsToDb = new Dictionary>() { + { typeof(bool).FullName, CsToDb.New(DbType.Boolean, "bit","bit NOT NULL", null, false, false) },{ typeof(bool?).FullName, CsToDb.New(DbType.Boolean, "bit","bit", null, true, null) }, + + { typeof(sbyte).FullName, CsToDb.New(DbType.SByte, "smallint", "smallint NOT NULL", false, false, 0) },{ typeof(sbyte?).FullName, CsToDb.New(DbType.SByte, "smallint", "smallint", false, true, null) }, + { typeof(short).FullName, CsToDb.New(DbType.Int16, "smallint","smallint NOT NULL", false, false, 0) },{ typeof(short?).FullName, CsToDb.New(DbType.Int16, "smallint", "smallint", false, true, null) }, + { typeof(int).FullName, CsToDb.New(DbType.Int32, "int", "int NOT NULL", false, false, 0) },{ typeof(int?).FullName, CsToDb.New(DbType.Int32, "int", "int", false, true, null) }, + { typeof(long).FullName, CsToDb.New(DbType.Int64, "bigint","bigint NOT NULL", false, false, 0) },{ typeof(long?).FullName, CsToDb.New(DbType.Int64, "bigint","bigint", false, true, null) }, + + { typeof(byte).FullName, CsToDb.New(DbType.Byte, "tinyint","tinyint NOT NULL", true, false, 0) },{ typeof(byte?).FullName, CsToDb.New(DbType.Byte, "tinyint","tinyint", true, true, null) }, + { typeof(ushort).FullName, CsToDb.New(DbType.UInt16, "int","int NOT NULL", true, false, 0) },{ typeof(ushort?).FullName, CsToDb.New(DbType.UInt16, "int", "int", true, true, null) }, + { typeof(uint).FullName, CsToDb.New(DbType.UInt32, "bigint", "bigint NOT NULL", true, false, 0) },{ typeof(uint?).FullName, CsToDb.New(DbType.UInt32, "bigint", "bigint", true, true, null) }, + { typeof(ulong).FullName, CsToDb.New(DbType.UInt64, "decimal", "decimal(20,0) NOT NULL", true, false, 0) },{ typeof(ulong?).FullName, CsToDb.New(DbType.UInt64, "decimal", "decimal(20,0)", true, true, null) }, + + { typeof(double).FullName, CsToDb.New(DbType.Double, "float", "float NOT NULL", false, false, 0) },{ typeof(double?).FullName, CsToDb.New(DbType.Double, "float", "float", false, true, null) }, + { typeof(float).FullName, CsToDb.New(DbType.Single, "real","real NOT NULL", false, false, 0) },{ typeof(float?).FullName, CsToDb.New(DbType.Single, "real","real", false, true, null) }, + { typeof(decimal).FullName, CsToDb.New(DbType.Decimal, "decimal", "decimal(10,2) NOT NULL", false, false, 0) },{ typeof(decimal?).FullName, CsToDb.New(DbType.Decimal, "decimal", "decimal(10,2)", false, true, null) }, + + { typeof(TimeSpan).FullName, CsToDb.New(DbType.Time, "time","time NOT NULL", false, false, 0) },{ typeof(TimeSpan?).FullName, CsToDb.New(DbType.Time, "time", "time",false, true, null) }, + { typeof(DateTime).FullName, CsToDb.New(DbType.DateTime, "datetime", "datetime NOT NULL", false, false, new DateTime(1970,1,1)) },{ typeof(DateTime?).FullName, CsToDb.New(DbType.DateTime, "datetime", "datetime", false, true, null) }, + { typeof(DateTimeOffset).FullName, CsToDb.New(DbType.DateTimeOffset, "datetimeoffset", "datetimeoffset NOT NULL", false, false, new DateTimeOffset(new DateTime(1970,1,1), TimeSpan.Zero)) },{ typeof(DateTimeOffset?).FullName, CsToDb.New(DbType.DateTimeOffset, "datetimeoffset", "datetimeoffset", false, true, null) }, + + { typeof(byte[]).FullName, CsToDb.New(DbType.Binary, "varbinary", "varbinary(255)", false, null, new byte[0]) }, + { typeof(string).FullName, CsToDb.New(DbType.String, "nvarchar", "nvarchar(255)", false, null, "") }, + { typeof(char).FullName, CsToDb.New(DbType.AnsiString, "char", "char(1) NULL", false, null, '\0') }, + + { typeof(Guid).FullName, CsToDb.New(DbType.Guid, "uniqueidentifier", "uniqueidentifier NOT NULL", false, false, Guid.Empty) },{ typeof(Guid?).FullName, CsToDb.New(DbType.Guid, "uniqueidentifier", "uniqueidentifier", false, true, null) }, + }; + + public override DbInfoResult GetDbInfo(Type type) + { + if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); + if (type.IsArray) return null; + var enumType = type.IsEnum ? type : null; + if (enumType == null && type.IsNullableType()) + { + var genericTypes = type.GetGenericArguments(); + if (genericTypes.Length == 1 && genericTypes.First().IsEnum) enumType = genericTypes.First(); + } + if (enumType != null) + { + var newItem = enumType.GetCustomAttributes(typeof(FlagsAttribute), false).Any() ? + CsToDb.New(DbType.Int32, "bigint", $"bigint{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()) : + CsToDb.New(DbType.Int64, "int", $"int{(type.IsEnum ? " NOT NULL" : "")}", false, type.IsEnum ? false : true, enumType.CreateInstanceGetDefaultValue()); + if (_dicCsToDb.ContainsKey(type.FullName) == false) + { + lock (_dicCsToDbLock) + { + if (_dicCsToDb.ContainsKey(type.FullName) == false) + _dicCsToDb.Add(type.FullName, newItem); + } + } + return new DbInfoResult((int)newItem.type, newItem.dbtype, newItem.dbtypeFull, newItem.isnullable, newItem.defaultValue); + } + return null; + } + + void AddOrUpdateMS_Description(StringBuilder sb, string schema, string table, string comment) + { + if (string.IsNullOrEmpty(comment)) + { + sb.AppendFormat(@" +IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', + 'SCHEMA', N'{0}', + 'TABLE', N'{1}', + NULL, NULL)) > 0) + EXEC sp_dropextendedproperty @name = N'MS_Description' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' +", schema.Replace("'", "''"), table.Replace("'", "''")); + return; + } + sb.AppendFormat(@" +IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', + 'SCHEMA', N'{0}', + 'TABLE', N'{1}', + NULL, NULL)) > 0) + EXEC sp_updateextendedproperty @name = N'MS_Description', @value = N'{2}' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' +ELSE + EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'{2}' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' +", schema.Replace("'", "''"), table.Replace("'", "''"), comment?.Replace("'", "''") ?? ""); + } + void AddOrUpdateMS_Description(StringBuilder sb, string schema, string table, string column, string comment) + { + if (string.IsNullOrEmpty(comment)) + { + sb.AppendFormat(@" +IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', + 'SCHEMA', N'{0}', + 'TABLE', N'{1}', + 'COLUMN', N'{2}')) > 0) + EXEC sp_dropextendedproperty @name = N'MS_Description' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' + , @level2type = 'COLUMN', @level2name = N'{2}' +", schema.Replace("'", "''"), table.Replace("'", "''"), column.Replace("'", "''")); + return; + } + sb.AppendFormat(@" +IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', + 'SCHEMA', N'{0}', + 'TABLE', N'{1}', + 'COLUMN', N'{2}')) > 0) + EXEC sp_updateextendedproperty @name = N'MS_Description', @value = N'{3}' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' + , @level2type = 'COLUMN', @level2name = N'{2}' +ELSE + EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'{3}' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' + , @level2type = 'COLUMN', @level2name = N'{2}' +", schema.Replace("'", "''"), table.Replace("'", "''"), column.Replace("'", "''"), comment?.Replace("'", "''") ?? ""); + } + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) + { + Object conn = null; + string database = null; + + try + { + conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5)); + database = conn.Value.Database; + + var sb = new StringBuilder(); + foreach (var obj in objects) + { + if (sb.Length > 0) sb.Append("\r\n"); + var tb = _commonUtils.GetTableByEntity(obj.entityType); + if (tb == null) throw new Exception(CoreStrings.S_Type_IsNot_Migrable(obj.entityType.FullName)); + if (tb.Columns.Any() == false) throw new Exception(CoreStrings.S_Type_IsNot_Migrable_0Attributes(obj.entityType.FullName)); + var tbname = _commonUtils.SplitTableName(tb.DbName); + if (tbname?.Length == 1) tbname = new[] { database, "dbo", tbname[0] }; + if (tbname?.Length == 2) tbname = new[] { database, tbname[0], tbname[1] }; + + var tboldname = _commonUtils.SplitTableName(tb.DbOldName); //旧表名 + if (tboldname?.Length == 1) tboldname = new[] { database, "dbo", tboldname[0] }; + if (tboldname?.Length == 2) tboldname = new[] { database, tboldname[0], tboldname[1] }; + if (string.IsNullOrEmpty(obj.tableName) == false) + { + var tbtmpname = _commonUtils.SplitTableName(obj.tableName); + if (tbtmpname?.Length == 1) tbtmpname = new[] { database, "dbo", tbtmpname[0] }; + if (tbtmpname?.Length == 2) tbtmpname = new[] { database, tbtmpname[0], tbtmpname[1] }; + if (tbname[0] != tbtmpname[0] || tbname[1] != tbtmpname[1] || tbname[2] != tbtmpname[2]) + { + tbname = tbtmpname; + tboldname = null; + } + } + //codefirst 不支持表名、模式名、数据库名中带 . + + if (string.Compare(tbname[0], database, true) != 0 && LocalExecuteScalar(database, $" select 1 from sys.databases where name='{tbname[0]}'") == null) //创建数据库 + LocalExecuteScalar(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 && LocalExecuteScalar(tbname[0], $" select 1 from sys.schemas where name='{tbname[1]}'") == null) //创建模式 + LocalExecuteScalar(tbname[0], $"create schema [{tbname[1]}] authorization [dbo]"); + + var sbalter = new StringBuilder(); + var istmpatler = false; //创建临时表,导入数据,删除旧表,修改 + if (LocalExecuteScalar(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 && LocalExecuteScalar(database, $" select 1 from sys.databases where name='{tboldname[0]}'") == null || + string.Compare(tboldname[1], tbname[1], true) != 0 && LocalExecuteScalar(tboldname[0], $" select 1 from sys.schemas where name='{tboldname[1]}'") == null || + LocalExecuteScalar(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) + { + //创建表 + var createTableName = _commonUtils.QuoteSqlName(tbname[1], tbname[2]); + sb.Append("use [").Append(tbname[0]).Append("];\r\nCREATE TABLE ").Append(createTableName).Append(" ( "); + var pkidx = 0; + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); + if (tbcol.Attribute.IsPrimary == true) + { + if (tb.Primarys.Length > 1) + { + if (pkidx == tb.Primarys.Length - 1) + sb.Append(" primary key (").Append(string.Join(", ", tb.Primarys.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(")"); + } + else + sb.Append(" primary key"); + pkidx++; + } + sb.Append(","); + } + sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(createTableName).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); + } + if (string.IsNullOrEmpty(tb.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tb.Comment); + continue; + } + //如果新表,旧表在一个数据库和模式下,直接修改表名 + if (string.Compare(tbname[0], tboldname[0], true) == 0 && + string.Compare(tbname[1], tboldname[1], true) == 0) + sbalter.Append("use [").Append(tbname[0]).Append(_commonUtils.FormatSql("];\r\nEXEC sp_rename {0}, {1};\r\n", _commonUtils.QuoteSqlName(tboldname[0], tboldname[1], tboldname[2]), 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 '(' + + case when a.max_length = -1 then 'MAX' + when b.name in ('nchar', 'nvarchar') then cast(a.max_length / 2 as varchar) + else cast(a.max_length as varchar) end + ')' + when b.name in ('numeric', 'decimal') then '(' + cast(a.precision as varchar) + ',' + cast(a.scale as varchar) + ')' + else '' end as 'sqltype' +,case when a.is_nullable = 1 then '1' else '0' end 'isnullable' +,case when a.is_identity = 1 then '1' else '0' end 'isidentity' +,(select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.column_id AND name = 'MS_Description') 'comment' +from sys.columns a +inner join sys.types b on b.user_type_id = a.user_type_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'[{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", + comment = string.Concat(a[4]) + }, StringComparer.CurrentCultureIgnoreCase); + + if (istmpatler == false) + { + foreach (var tbcol in tb.ColumnsByPosition) + { + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); + 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 (string.Compare(tbstructcol.column, tbcol.Attribute.OldName, true) == 0) + //修改列名 + sbalter.Append(_commonUtils.FormatSql("EXEC sp_rename {0}, {1}, 'COLUMN';\r\n", $"{tbname[0]}.{tbname[1]}.{tbname[2]}.{tbstructcol.column}", tbcol.Attribute.Name)); + if (isCommentChanged) + //修改备备注 + AddOrUpdateMS_Description(sbalter, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); + 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 == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sbalter.Append(" identity(1,1)"); + if (tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) sbalter.Append(" default(").Append(GetTransferDbDefaultValue(tbcol)).Append(")"); + sbalter.Append(";\r\n"); + if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sbalter, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); + } + } + if (istmpatler == false) + { + var dsuksql = string.Format(@" +use [{0}]; +select +c.name +,b.name +,case when a.is_descending_key = 1 then 1 else 0 end +,case when b.is_unique = 1 then 1 else 0 end +from sys.index_columns a +inner join sys.indexes b on b.object_id = a.object_id and b.index_id = a.index_id +left join sys.columns c on c.object_id = a.object_id and c.column_id = a.column_id +where a.object_id in (object_id(N'[{1}].[{2}]')) and b.is_primary_key = 0; +use [" + database + "];", tboldname ?? tbname); + var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]), string.Concat(a[2]), string.Concat(a[3]) }); + foreach (var uk in tb.Indexes) + { + if (string.IsNullOrEmpty(uk.Name) || uk.Columns.Any() == false) continue; + var ukname = ReplaceIndexName(uk.Name, tbname[1]); + var dsukfind1 = dsuk.Where(a => string.Compare(a[1], ukname, true) == 0).ToArray(); + if (dsukfind1.Any() == false || dsukfind1.Length != uk.Columns.Length || dsukfind1.Where(a => (a[3] == "1") == uk.IsUnique && uk.Columns.Where(b => string.Compare(b.Column.Attribute.Name, a[0], true) == 0 && (a[2] == "1") == b.IsDesc).Any()).Count() != uk.Columns.Length) + { + if (dsukfind1.Any()) sbalter.Append("DROP INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[1], tbname[2])).Append(";\r\n"); + sbalter.Append("CREATE "); + if (uk.IsUnique) sbalter.Append("UNIQUE "); + sbalter.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ukname)).Append(" ON ").Append(_commonUtils.QuoteSqlName(tbname[1], tbname[2])).Append("("); + foreach (var tbcol in uk.Columns) + { + sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sbalter.Append(" DESC"); + sbalter.Append(", "); + } + sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n"); + } + } + } + if (istmpatler == false) + { + var dbcommentsql = $" SELECT value from fn_listextendedproperty('MS_Description', 'schema', N'{tbname[1].Replace("'", "''")}', 'table', N'{tbname[2].Replace("'", "''")}', NULL, NULL)"; + if (string.Compare(tbname[0], database, true) != 0) dbcommentsql = $"use [{tbname[0]}];{dbcommentsql};use [{database}];"; + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, dbcommentsql)); + if (dbcomment != (tb.Comment ?? "")) + AddOrUpdateMS_Description(sbalter, tbname[1], tbname[2], tb.Comment); + + if (sbalter.Length > 0) + sb.Append($"use [{tbname[0]}];").Append(sbalter).Append("\r\nuse [").Append(database).Append("];"); + continue; + } + //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 + 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(" ( "); + var pkidx2 = 0; + foreach (var tbcol in tb.ColumnsByPosition) + { + sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType); + if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("identity", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" identity(1,1)"); + if (tbcol.Attribute.IsPrimary == true) + { + if (tb.Primarys.Length > 1) + { + if (pkidx2 == tb.Primarys.Length - 1) + sb.Append(" primary key (").Append(string.Join(", ", tb.Primarys.Select(a => _commonUtils.QuoteSqlName(a.Attribute.Name)))).Append(")"); + } + else + sb.Append(" primary key"); + pkidx2++; + } + sb.Append(","); + idents = idents || tbcol.Attribute.IsIdentity == true; + } + sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); + //备注 + foreach (var tbcol in tb.ColumnsByPosition) + { + if (string.IsNullOrEmpty(tbcol.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], $"FreeSqlTmp_{tbname[2]}", tbcol.Attribute.Name, tbcol.Comment); + } + if (string.IsNullOrEmpty(tb.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], $"FreeSqlTmp_{tbname[2]}", tb.Comment); + + if ((_commonUtils as CustomSqlServerUtils).ServerVersion > 9) //SqlServer 2008+ + 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.ColumnsByPosition) + sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); + sb.Remove(sb.Length - 2, 2).Append(")\r\n\t\tSELECT "); + foreach (var tbcol in tb.ColumnsByPosition) + { + var insertvalue = "NULL"; + if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || + string.IsNullOrEmpty(tbcol.Attribute.OldName) == false && tbstruct.TryGetValue(tbcol.Attribute.OldName, out tbstructcol)) + { + insertvalue = _commonUtils.QuoteSqlName(tbstructcol.column); + if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + insertvalue = $"cast({insertvalue} as {tbcol.Attribute.DbType.Split(' ').First()})"; + if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) + insertvalue = $"isnull({insertvalue},{GetTransferDbDefaultValue(tbcol)})"; + } + else if (tbcol.Attribute.IsNullable == false) + if (tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) + insertvalue = GetTransferDbDefaultValue(tbcol); + sb.Append(insertvalue.Replace("'", "''")).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"); + //创建表的索引 + foreach (var uk in tb.Indexes) + { + sb.Append("CREATE "); + if (uk.IsUnique) sb.Append("UNIQUE "); + sb.Append("INDEX ").Append(_commonUtils.QuoteSqlName(ReplaceIndexName(uk.Name, tbname[1]))).Append(" ON ").Append(tablename).Append("("); + foreach (var tbcol in uk.Columns) + { + sb.Append(_commonUtils.QuoteSqlName(tbcol.Column.Attribute.Name)); + if (tbcol.IsDesc) sb.Append(" DESC"); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2).Append(");\r\n"); + } + sb.Append("COMMIT;\r\n"); + } + return sb.Length == 0 ? null : sb.ToString(); + } + finally + { + try + { + if (string.IsNullOrEmpty(database) == false) + conn.Value.ChangeDatabase(database); + _orm.Ado.MasterPool.Return(conn); + } + catch + { + _orm.Ado.MasterPool.Return(conn, true); + } + } + + object LocalExecuteScalar(string db, string sql) + { + if (string.Compare(database, db) != 0) conn.Value.ChangeDatabase(db); + 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); + } + } + } + string GetTransferDbDefaultValue(ColumnInfo col) + { + var ddv = col.DbDefaultValue; + if (string.IsNullOrEmpty(ddv) || ddv == "NULL") return ddv; + if (col.Attribute.MapType.NullableTypeOrThis() == typeof(DateTime) && DateTime.TryParse(ddv, out var trydt)) + { + if (col.Attribute.DbType.Contains("SMALLDATETIME") && trydt < new DateTime(1900, 1, 1)) ddv = _commonUtils.FormatSql("{0}", new DateTime(1900, 1, 1)); + else if (col.Attribute.DbType.Contains("DATETIME") && trydt < new DateTime(1753, 1, 1)) ddv = _commonUtils.FormatSql("{0}", new DateTime(1753, 1, 1)); + else if (col.Attribute.DbType.Contains("DATE") && trydt < new DateTime(0001, 1, 1)) ddv = _commonUtils.FormatSql("{0}", new DateTime(0001, 1, 1)); + } + return ddv; + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerDbFirst.cs b/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerDbFirst.cs new file mode 100644 index 00000000..b21175aa --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerDbFirst.cs @@ -0,0 +1,521 @@ +using FreeSql.DatabaseModel; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; + +namespace FreeSql.Custom.SqlServer +{ + class CustomSqlServerDbFirst : IDbFirst + { + IFreeSql _orm; + protected CommonUtils _commonUtils; + protected CommonExpression _commonExpression; + public CustomSqlServerDbFirst(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) + { + _orm = orm; + _commonUtils = commonUtils; + _commonExpression = commonExpression; + } + + public int GetDbType(DbColumnInfo column) => (int)GetSqlDbType(column); + DbType GetSqlDbType(DbColumnInfo column) + { + switch (column.DbTypeText?.ToLower()) + { + case "bit": return DbType.Boolean; + case "tinyint": return DbType.Byte; + case "smallint": return DbType.Int16; + case "int": return DbType.Int32; + case "bigint": return DbType.Int64; + case "numeric": + case "decimal": return DbType.Decimal; + case "smallmoney": return DbType.Decimal; + case "money": return DbType.Decimal; + case "float": return DbType.Double; + case "real": return DbType.Single; + case "date": return DbType.Date; + case "datetime": return DbType.DateTime; + case "datetime2": return DbType.DateTime2; + case "datetimeoffset": return DbType.DateTime; + case "smalldatetime": return DbType.DateTime; + case "time": return DbType.Time; + case "char": return DbType.AnsiString; + case "varchar": return DbType.String; + case "text": return DbType.String; + case "nchar": return DbType.String; + case "nvarchar": return DbType.String; + case "ntext": return DbType.String; + case "binary": return DbType.Binary; + case "varbinary": return DbType.Binary; + case "image": return DbType.Binary; + case "timestamp": return DbType.Binary; + case "uniqueidentifier": return DbType.Guid; + default: return DbType.String; + } + } + + static readonly Dictionary _dicDbToCs = new Dictionary() { + { (int)DbType.Boolean, new DbToCs("(bool?)", "{0} == \"1\"", "{0} == true ? \"1\" : \"0\"", "bool?", typeof(bool), typeof(bool?), "{0}.Value", "GetBoolean") }, + + { (int)DbType.SByte, new DbToCs("(sbyte?)", "sbyte.Parse({0})", "{0}.ToString()", "sbyte?", typeof(sbyte), typeof(sbyte?), "{0}.Value", "GetInt16") }, + { (int)DbType.Int16, new DbToCs("(short?)", "short.Parse({0})", "{0}.ToString()", "short?", typeof(short), typeof(short?), "{0}.Value", "GetInt16") }, + { (int)DbType.Int32, new DbToCs("(int?)", "int.Parse({0})", "{0}.ToString()", "int?", typeof(int), typeof(int?), "{0}.Value", "GetInt32") }, + { (int)DbType.Int64, new DbToCs("(long?)", "long.Parse({0})", "{0}.ToString()", "long?", typeof(long), typeof(long?), "{0}.Value", "GetInt64") }, + + { (int)DbType.Byte, new DbToCs("(byte?)", "byte.Parse({0})", "{0}.ToString()", "byte?", typeof(byte), typeof(byte?), "{0}.Value", "GetByte") }, + { (int)DbType.UInt16, new DbToCs("(ushort?)", "ushort.Parse({0})", "{0}.ToString()", "ushort?", typeof(ushort), typeof(ushort?), "{0}.Value", "GetInt32") }, + { (int)DbType.UInt32, new DbToCs("(uint?)", "uint.Parse({0})", "{0}.ToString()", "uint?", typeof(uint), typeof(uint?), "{0}.Value", "GetInt64") }, + { (int)DbType.UInt64, new DbToCs("(ulong?)", "ulong.Parse({0})", "{0}.ToString()", "ulong?", typeof(ulong), typeof(ulong?), "{0}.Value", "GetInt64") }, + + { (int)DbType.Decimal, new DbToCs("(decimal?)", "decimal.Parse({0})", "{0}.ToString()", "decimal?", typeof(decimal), typeof(decimal?), "{0}.Value", "GetDecimal") }, + { (int)DbType.Double, new DbToCs("(double?)", "double.Parse({0})", "{0}.ToString()", "double?", typeof(double), typeof(double?), "{0}.Value", "GetDouble") }, + { (int)DbType.Single, new DbToCs("(float?)", "float.Parse({0})", "{0}.ToString()", "float?", typeof(float), typeof(float?), "{0}.Value", "GetFloat") }, + + { (int)DbType.Time, new DbToCs("(TimeSpan?)", "TimeSpan.Parse(double.Parse({0}))", "{0}.Ticks.ToString()", "TimeSpan?", typeof(TimeSpan), typeof(TimeSpan?), "{0}.Value", "GetValue") }, + { (int)DbType.Date, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)DbType.DateTime, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + { (int)DbType.DateTime2, new DbToCs("(DateTime?)", "new DateTime(long.Parse({0}))", "{0}.Ticks.ToString()", "DateTime?", typeof(DateTime), typeof(DateTime?), "{0}.Value", "GetDateTime") }, + + { (int)DbType.Binary, new DbToCs("(byte[])", "Convert.FromBase64String({0})", "Convert.ToBase64String({0})", "byte[]", typeof(byte[]), typeof(byte[]), "{0}", "GetValue") }, + + { (int)DbType.AnsiString, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + { (int)DbType.String, new DbToCs("", "{0}.Replace(StringifySplit, \"|\")", "{0}.Replace(\"|\", StringifySplit)", "string", typeof(string), typeof(string), "{0}", "GetString") }, + + { (int)DbType.Guid, new DbToCs("(Guid?)", "Guid.Parse({0})", "{0}.ToString()", "Guid?", typeof(Guid), typeof(Guid?), "{0}.Value", "GetGuid") }, + }; + + public string GetCsConvert(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csConvert : trydc.csConvert.Replace("?", "")) : null; + public string GetCsParse(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csParse : null; + public string GetCsStringify(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csStringify : null; + public string GetCsType(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? (column.IsNullable ? trydc.csType : trydc.csType.Replace("?", "")) : null; + public Type GetCsTypeInfo(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeInfo : null; + public string GetCsTypeValue(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.csTypeValue : null; + public string GetDataReaderMethod(DbColumnInfo column) => _dicDbToCs.TryGetValue(column.DbType, out var trydc) ? trydc.dataReaderMethod : null; + + public List GetDatabases() + { + var sql = @" select name from sys.databases where name not in ('master','tempdb','model','msdb')"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + return ds.Select(a => a.FirstOrDefault()?.ToString()).ToList(); + } + + public bool ExistsTable(string name, bool ignoreCase) + { + if (string.IsNullOrEmpty(name)) return false; + var olddatabase = ""; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + olddatabase = conn.Value.Database; + } + var tbname = _commonUtils.SplitTableName(name); + if (tbname?.Length == 1) tbname = new[] { olddatabase, "dbo", tbname[0] }; + if (tbname?.Length == 2) tbname = new[] { olddatabase, tbname[0], tbname[1] }; + tbname = tbname.Select(a => a.ToLower()).ToArray(); + var sql = $@" +use [{tbname[0]}]; +select +1 +from sys.tables a +inner join sys.schemas b on b.schema_id = a.schema_id +where lower(b.name)={_commonUtils.FormatSql("{0}", tbname[1])} and lower(a.name)={_commonUtils.FormatSql("{0}", tbname[2])} +; +use [{olddatabase}]; +"; + return string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, sql)) == "1"; + } + public DbTableInfo GetTableByName(string name, bool ignoreCase = true) => GetTables(null, name, ignoreCase)?.FirstOrDefault(); + public List GetTablesByDatabase(params string[] database) => GetTables(database, null, false); + + public List GetTables(string[] database, string tablename, bool ignoreCase) + { + var olddatabase = ""; + using (var conn = _orm.Ado.MasterPool.Get(TimeSpan.FromSeconds(5))) + { + olddatabase = conn.Value.Database; + } + string[] tbname = null; + string[] dbs = database == null || database.Any() == false ? new[] { olddatabase } : database; + if (string.IsNullOrEmpty(tablename) == false) + { + tbname = _commonUtils.SplitTableName(tablename); + if (tbname?.Length == 1) tbname = new[] { olddatabase, "dbo", tbname[0] }; + if (tbname?.Length == 2) tbname = new[] { olddatabase, tbname[0], tbname[1] }; + tbname = tbname.Select(a => a.ToLower()).ToArray(); + dbs = new[] { tbname[0] }; + } + var tables = new List(); + + foreach (var db in dbs) + { + if (string.IsNullOrEmpty(db)) continue; + + var loc1 = new List(); + var loc2 = new Dictionary(); + var loc3 = new Dictionary>(); + + var sql = $@" +use [{db}]; +select * from ( +select + a.object_id +,b.name 'owner' +,a.name 'name' +,(select value from sys.extended_properties where major_id = a.object_id AND minor_id = 0 AND name = 'MS_Description') 'comment' +,'TABLE' type +from sys.tables a +inner join sys.schemas b on b.schema_id = a.schema_id +where not(b.name = 'dbo' and a.name = 'sysdiagrams') +union all +select + a.object_id +,b.name 'owner' +,a.name 'name' +,(select value from sys.extended_properties where major_id = a.object_id AND minor_id = 0 AND name = 'MS_Description') 'comment' +,'VIEW' type +from sys.views a +inner join sys.schemas b on b.schema_id = a.schema_id +union all +select + a.object_id +,b.name 'owner' +,a.name 'name' +,(select value from sys.extended_properties where major_id = a.object_id AND minor_id = 0 AND name = 'MS_Description') 'comment' +,'StoreProcedure' type +from sys.procedures a +inner join sys.schemas b on b.schema_id = a.schema_id +where a.type = 'P' and charindex('diagram', a.name) = 0 +) ft_dbf{(tbname == null ? "" : _commonUtils.FormatSql(" where lower([owner])={0} and lower([name])={1}", new[] { tbname[1], tbname[2] }))} +order by type desc, [owner], [name]; +use [{olddatabase}]; +"; + var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var loc6 = new List(); + var loc66 = new List(); + var loc6_1000 = new List(); + var loc66_1000 = new List(); + foreach (object[] row in ds) + { + int object_id = int.Parse(string.Concat(row[0])); + var owner = string.Concat(row[1]); + var table = string.Concat(row[2]); + var comment = string.Concat(row[3]); + Enum.TryParse(string.Concat(row[4]), out var type); + loc2.Add(object_id, new DbTableInfo { Id = object_id.ToString(), Schema = owner, Name = table, Comment = comment, Type = type }); + loc3.Add(object_id, new Dictionary()); + switch (type) + { + case DbTableType.VIEW: + case DbTableType.TABLE: + loc6_1000.Add(object_id); + if (loc6_1000.Count >= 500) + { + loc6.Add(loc6_1000.ToArray()); + loc6_1000.Clear(); + } + break; + case DbTableType.StoreProcedure: + loc66_1000.Add(object_id); + if (loc66_1000.Count >= 500) + { + loc66.Add(loc66_1000.ToArray()); + loc66_1000.Clear(); + } + break; + } + } + if (loc6_1000.Count > 0) loc6.Add(loc6_1000.ToArray()); + if (loc66_1000.Count > 0) loc66.Add(loc66_1000.ToArray()); + + if (loc6.Count == 0) return loc1; + Func, StringBuilder> getloc8Sb = loclist => + { + if (loclist.Count == 0) return new StringBuilder(); + var loc8sb = new StringBuilder().Append("("); + for (var loc8sbidx = 0; loc8sbidx < loclist.Count; loc8sbidx++) + { + if (loc8sbidx > 0) loc8sb.Append(" OR "); + loc8sb.Append("a.table_name in ("); + for (var loc8sbidx2 = 0; loc8sbidx2 < loclist[loc8sbidx].Length; loc8sbidx2++) + { + if (loc8sbidx2 > 0) loc8sb.Append(","); + loc8sb.Append(loclist[loc8sbidx][loc8sbidx2]); + } + loc8sb.Append(")"); + } + loc8sb.Append(")"); + return loc8sb; + }; + var loc8 = getloc8Sb(loc6); + var loc88 = getloc8Sb(loc66); + + var tsql_place = @" + +select +isnull(e.name,'') + '.' + isnull(d.name,'') +,a.object_id +,a.name 'column' +,b.name 'type' +,case + when b.name in ('text', 'ntext', 'image') then -1 + when b.name in ('nchar', 'nvarchar') then a.max_length / 2 + else a.max_length end 'length' +,b.name + case + when b.name in ('char', 'varchar', 'nchar', 'nvarchar', 'binary', 'varbinary') then '(' + + case when a.max_length = -1 then 'MAX' + when b.name in ('nchar', 'nvarchar') then cast(a.max_length / 2 as varchar) + else cast(a.max_length as varchar) end + ')' + when b.name in ('numeric', 'decimal') then '(' + cast(a.precision as varchar) + ',' + cast(a.scale as varchar) + ')' + else '' end as 'sqltype' +,( select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.column_id AND name = 'MS_Description') 'comment' +{0} a +inner join sys.types b on b.user_type_id = a.user_type_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{2} +where {1} +"; + sql = string.Format(tsql_place, @" +,a.is_nullable 'isnullable' +,a.is_identity 'isidentity' +,f.text as 'defaultvalue' +from sys.columns", loc8.ToString().Replace("a.table_name", "a.object_id"), @" +left join syscomments f on f.id = a.default_object_id +"); + if (loc88.Length > 0) + { + sql += "union all" + + string.Format(tsql_place.Replace( + " select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.column_id", + " select value from sys.extended_properties where major_id = a.object_id AND minor_id = a.parameter_id"), @" +,cast(0 as bit) 'isnullable' +,a.is_output 'isidentity' +,'' as 'defaultvalue' +from sys.parameters", loc88.ToString().Replace("a.table_name", "a.object_id"), ""); + } + sql = $"use [{db}];{sql};use [{olddatabase}]; "; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var position = 0; + foreach (object[] row in ds) + { + var table_id = string.Concat(row[0]); + var object_id = int.Parse(string.Concat(row[1])); + var column = string.Concat(row[2]); + var type = string.Concat(row[3]); + var max_length = int.Parse(string.Concat(row[4])); + var sqlType = string.Concat(row[5]); + var comment = string.Concat(row[6]); + var is_nullable = bool.Parse(string.Concat(row[7])); + var is_identity = bool.Parse(string.Concat(row[8])); + var defaultValue = string.Concat(row[9]); + if (max_length == 0) max_length = -1; + + loc3[object_id].Add(column, new DbColumnInfo + { + Name = column, + MaxLength = max_length, + IsIdentity = is_identity, + IsNullable = is_nullable, + IsPrimary = false, + DbTypeText = type, + DbTypeTextFull = sqlType, + Table = loc2[object_id], + Comment = comment, + DefaultValue = defaultValue, + Position = ++position + }); + loc3[object_id][column].DbType = this.GetDbType(loc3[object_id][column]); + loc3[object_id][column].CsType = this.GetCsTypeInfo(loc3[object_id][column]); + } + + sql = $@" +use [{db}]; +select + a.object_id 'object_id' +,c.name 'column' +,b.name 'index_id' +,b.is_unique 'isunique' +,b.is_primary_key 'isprimarykey' +,cast(case when b.type_desc = 'CLUSTERED' then 1 else 0 end as bit) 'isclustered' +,case when a.is_descending_key = 1 then 1 else 0 end 'isdesc' +from sys.index_columns a +inner join sys.indexes b on b.object_id = a.object_id and b.index_id = a.index_id +left join sys.columns c on c.object_id = a.object_id and c.column_id = a.column_id +where {loc8.ToString().Replace("a.table_name", "a.object_id")} +; +use [{olddatabase}]; +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var indexColumns = new Dictionary>(); + var uniqueColumns = new Dictionary>(); + foreach (object[] row in ds) + { + int object_id = int.Parse(string.Concat(row[0])); + string column = string.Concat(row[1]); + string index_id = string.Concat(row[2]); + bool is_unique = bool.Parse(string.Concat(row[3])); + bool is_primary_key = bool.Parse(string.Concat(row[4])); + bool is_clustered = bool.Parse(string.Concat(row[5])); + bool is_desc = string.Concat(row[6]) == "1"; + + if (loc3.ContainsKey(object_id) == false || loc3[object_id].ContainsKey(column) == false) continue; + DbColumnInfo loc9 = loc3[object_id][column]; + if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; + + Dictionary loc10 = null; + DbIndexInfo loc11 = null; + if (!indexColumns.TryGetValue(object_id, out loc10)) + indexColumns.Add(object_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + if (is_unique && !is_primary_key) + { + if (!uniqueColumns.TryGetValue(object_id, out loc10)) + uniqueColumns.Add(object_id, loc10 = new Dictionary()); + if (!loc10.TryGetValue(index_id, out loc11)) + loc10.Add(index_id, loc11 = new DbIndexInfo()); + loc11.Columns.Add(new DbIndexColumnInfo { Column = loc9, IsDesc = is_desc }); + } + } + foreach (var object_id in indexColumns.Keys) + { + foreach (var column in indexColumns[object_id]) + loc2[object_id].IndexesDict.Add(column.Key, column.Value); + } + foreach (var object_id in uniqueColumns.Keys) + { + foreach (var column in uniqueColumns[object_id]) + { + column.Value.Columns.Sort((c1, c2) => c1.Column.Name.CompareTo(c2.Column.Name)); + loc2[object_id].UniquesDict.Add(column.Key, column.Value); + } + } + + if (tbname == null) + { + sql = $@" +use [{db}]; +select + b.object_id 'object_id' +,c.name 'column' +,e.name 'fkid' +,a.referenced_object_id +,cast(1 as bit) 'isforeignkey' +,d.name 'referenced_column' +,null 'referenced_sln' +,null 'referenced_table' +from sys.foreign_key_columns a +inner join sys.tables b on b.object_id = a.parent_object_id +inner join sys.columns c on c.object_id = a.parent_object_id and c.column_id = a.parent_column_id +inner join sys.columns d on d.object_id = a.referenced_object_id and d.column_id = a.referenced_column_id +left join sys.foreign_keys e on e.object_id = a.constraint_object_id +where {loc8.ToString().Replace("a.table_name", "b.object_id")} +; +use [{olddatabase}]; +"; + ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); + if (ds == null) return loc1; + + var fkColumns = new Dictionary>(); + foreach (object[] row in ds) + { + int object_id, referenced_object_id; + int.TryParse(string.Concat(row[0]), out object_id); + var column = string.Concat(row[1]); + string fk_id = string.Concat(row[2]); + int.TryParse(string.Concat(row[3]), out referenced_object_id); + var is_foreign_key = bool.Parse(string.Concat(row[4])); + var referenced_column = string.Concat(row[5]); + var referenced_db = string.Concat(row[6]); + var referenced_table = string.Concat(row[7]); + DbColumnInfo loc9 = loc3[object_id][column]; + DbTableInfo loc10 = null; + DbColumnInfo loc11 = null; + bool isThisSln = referenced_object_id != 0; + + if (isThisSln) + { + loc10 = loc2[referenced_object_id]; + loc11 = loc3[referenced_object_id][referenced_column]; + } + else + { + + } + Dictionary loc12 = null; + DbForeignInfo loc13 = null; + if (!fkColumns.TryGetValue(object_id, out loc12)) + fkColumns.Add(object_id, loc12 = new Dictionary()); + if (!loc12.TryGetValue(fk_id, out loc13)) + loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[object_id], ReferencedTable = loc10 }); + loc13.Columns.Add(loc9); + loc13.ReferencedColumns.Add(loc11); + } + foreach (var table_id in fkColumns.Keys) + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); + } + + foreach (var table_id in loc3.Keys) + { + foreach (var loc5 in loc3[table_id].Values) + { + loc2[table_id].Columns.Add(loc5); + if (loc5.IsIdentity) loc2[table_id].Identitys.Add(loc5); + if (loc5.IsPrimary) loc2[table_id].Primarys.Add(loc5); + } + } + foreach (var loc4 in loc2.Values) + { + //if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) + //{ + // foreach (var loc5 in loc4.UniquesDict.First().Value.Columns) + // { + // loc5.Column.IsPrimary = true; + // loc4.Primarys.Add(loc5.Column); + // } + //} + loc4.Primarys.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc4.Columns.Sort((c1, c2) => + { + int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); + if (compare == 0) + { + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); + compare = b2.CompareTo(b1); + } + if (compare == 0) compare = c1.Name.CompareTo(c2.Name); + return compare; + }); + loc1.Add(loc4); + } + loc1.Sort((t1, t2) => + { + var ret = t1.Schema.CompareTo(t2.Schema); + if (ret == 0) ret = t1.Name.CompareTo(t2.Name); + return ret; + }); + + loc2.Clear(); + loc3.Clear(); + tables.AddRange(loc1); + } + return tables; + } + + public List GetEnumsByDatabase(params string[] database) + { + return new List(); + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerExpression.cs b/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerExpression.cs new file mode 100644 index 00000000..3fd9cacf --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerExpression.cs @@ -0,0 +1,558 @@ +using FreeSql.Internal; +using System; +using System.Collections; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; + +namespace FreeSql.Custom.SqlServer +{ + class CustomSqlServerExpression : CommonExpression + { + + public CustomSqlServerExpression(CommonUtils common) : base(common) { } + + public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.NodeType) + { + case ExpressionType.ArrayLength: + var arrOper = (exp as UnaryExpression)?.Operand; + if (arrOper.Type == typeof(byte[])) return $"datalength({getExp(arrOper)})"; + break; + case ExpressionType.Convert: + var operandExp = (exp as UnaryExpression)?.Operand; + var gentype = exp.Type.NullableTypeOrThis(); + if (gentype != operandExp.Type.NullableTypeOrThis()) + { + switch (gentype.ToString()) + { + case "System.Boolean": return $"(cast({getExp(operandExp)} as varchar) not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(operandExp)} as tinyint)"; + case "System.Char": return $"substring(cast({getExp(operandExp)} as nvarchar),1,1)"; + case "System.DateTime": return ExpressionConstDateTime(operandExp) ?? $"cast({getExp(operandExp)} as datetime)"; + case "System.Decimal": return $"cast({getExp(operandExp)} as decimal(36,18))"; + case "System.Double": return $"cast({getExp(operandExp)} as decimal(32,16))"; + case "System.Int16": return $"cast({getExp(operandExp)} as smallint)"; + case "System.Int32": return $"cast({getExp(operandExp)} as int)"; + case "System.Int64": return $"cast({getExp(operandExp)} as bigint)"; + case "System.SByte": return $"cast({getExp(operandExp)} as tinyint)"; + case "System.Single": return $"cast({getExp(operandExp)} as decimal(14,7))"; + case "System.String": + return gentype == typeof(Guid) ? + $"cast({getExp(operandExp)} as varchar(36))" : + $"cast({getExp(operandExp)} as nvarchar{(gentype.IsNumberType() || gentype.IsEnum ? "(100)" : "(max)")})"; + case "System.UInt16": return $"cast({getExp(operandExp)} as smallint)"; + case "System.UInt32": return $"cast({getExp(operandExp)} as int)"; + case "System.UInt64": return $"cast({getExp(operandExp)} as bigint)"; + case "System.Guid": return $"cast({getExp(operandExp)} as uniqueidentifier)"; + } + } + break; + case ExpressionType.Call: + var callExp = exp as MethodCallExpression; + + switch (callExp.Method.Name) + { + case "Parse": + case "TryParse": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Boolean": return $"(cast({getExp(callExp.Arguments[0])} as varchar) not in ('0','false'))"; + case "System.Byte": return $"cast({getExp(callExp.Arguments[0])} as tinyint)"; + case "System.Char": return $"substring(cast({getExp(callExp.Arguments[0])} as nvarchar),1,1)"; + case "System.DateTime": return ExpressionConstDateTime(callExp.Arguments[0]) ?? $"cast({getExp(callExp.Arguments[0])} as datetime)"; + case "System.Decimal": return $"cast({getExp(callExp.Arguments[0])} as decimal(36,18))"; + case "System.Double": return $"cast({getExp(callExp.Arguments[0])} as decimal(32,16))"; + case "System.Int16": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; + case "System.Int32": return $"cast({getExp(callExp.Arguments[0])} as int)"; + case "System.Int64": return $"cast({getExp(callExp.Arguments[0])} as bigint)"; + case "System.SByte": return $"cast({getExp(callExp.Arguments[0])} as tinyint)"; + case "System.Single": return $"cast({getExp(callExp.Arguments[0])} as decimal(14,7))"; + case "System.UInt16": return $"cast({getExp(callExp.Arguments[0])} as smallint)"; + case "System.UInt32": return $"cast({getExp(callExp.Arguments[0])} as int)"; + case "System.UInt64": return $"cast({getExp(callExp.Arguments[0])} as bigint)"; + case "System.Guid": return $"cast({getExp(callExp.Arguments[0])} as uniqueidentifier)"; + } + return null; + case "NewGuid": + switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString()) + { + case "System.Guid": return $"newid()"; + } + return null; + case "Next": + if (callExp.Object?.Type == typeof(Random)) return "cast(rand()*1000000000 as int)"; + return null; + case "NextDouble": + if (callExp.Object?.Type == typeof(Random)) return "rand()"; + return null; + case "Random": + if (callExp.Method.DeclaringType.IsNumberType()) return "rand()"; + return null; + case "ToString": + var gentype2 = callExp.Object.Type.NullableTypeOrThis(); + if (callExp.Object != null) return callExp.Arguments.Count == 0 ? (gentype2 == typeof(Guid) ? + $"cast({getExp(callExp.Object)} as varchar(36))" : + $"cast({getExp(callExp.Object)} as nvarchar{(gentype2.IsNumberType() || gentype2.IsEnum ? "(100)" : "(max)")})") : null; + return null; + } + + var objExp = callExp.Object; + var objType = objExp?.Type; + if (objType?.FullName == "System.Byte[]") return null; + + var argIndex = 0; + if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable)) + { + objExp = callExp.Arguments.FirstOrDefault(); + objType = objExp?.Type; + argIndex++; + + if (objType == typeof(string)) + { + switch (callExp.Method.Name) + { + case "First": + case "FirstOrDefault": + return $"substring({getExp(callExp.Arguments[0])}, 1, 1)"; + } + } + } + if (objType == null) objType = callExp.Method.DeclaringType; + if (objType != null || objType.IsArrayOrList()) + { + if (argIndex >= callExp.Arguments.Count) break; + tsc.SetMapColumnTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = objExp?.NodeType == ExpressionType.MemberAccess ? tsc.SetDbParamsReturnOld(null) : null; //#900 UseGenerateCommandParameterWithLambda(true) 子查询 bug、以及 #1173 参数化 bug + tsc.isNotSetMapColumnTmp = true; + var left = objExp == null ? null : getExp(objExp); + tsc.isNotSetMapColumnTmp = false; + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + if (oldDbParams != null) tsc.SetDbParamsReturnOld(oldDbParams); + switch (callExp.Method.Name) + { + case "Contains": + //判断 in //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + } + } + break; + case ExpressionType.NewArrayInit: + var arrExp = exp as NewArrayExpression; + var arrSb = new StringBuilder(); + arrSb.Append("("); + for (var a = 0; a < arrExp.Expressions.Count; a++) + { + if (a > 0) arrSb.Append(","); + if (a % 500 == 499) arrSb.Append(" \r\n \r\n"); //500元素分割, 3空格\r\n4空格 + arrSb.Append(getExp(arrExp.Expressions[a])); + } + if (arrSb.Length == 1) arrSb.Append("NULL"); + return arrSb.Append(")").ToString(); + case ExpressionType.ListInit: + var listExp = exp as ListInitExpression; + var listSb = new StringBuilder(); + listSb.Append("("); + for (var a = 0; a < listExp.Initializers.Count; a++) + { + if (listExp.Initializers[a].Arguments.Any() == false) continue; + if (a > 0) listSb.Append(","); + listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault())); + } + if (listSb.Length == 1) listSb.Append("NULL"); + return listSb.Append(")").ToString(); + case ExpressionType.New: + var newExp = exp as NewExpression; + if (typeof(IList).IsAssignableFrom(newExp.Type)) + { + if (newExp.Arguments.Count == 0) return "(NULL)"; + if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false) return "(NULL)"; + return getExp(newExp.Arguments[0]); + } + return null; + } + return null; + } + + public override string ExpressionLambdaToSqlMemberAccessString(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Empty": return "''"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Length": return $"len({left})"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Now": return _common.Now; + case "UtcNow": return _common.NowUtc; + case "Today": return "convert(char(10),getdate(),120)"; + case "MinValue": return "'1753/1/1 0:00:00'"; + case "MaxValue": return "'9999/12/31 23:59:59'"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Date": return $"convert(char(10),{left},120)"; + case "TimeOfDay": return $"datediff(second, convert(char(10),{left},120), {left})"; + case "DayOfWeek": return $"(datepart(weekday, {left})-1)"; + case "Day": return $"datepart(day, {left})"; + case "DayOfYear": return $"datepart(dayofyear, {left})"; + case "Month": return $"datepart(month, {left})"; + case "Year": return $"datepart(year, {left})"; + case "Hour": return $"datepart(hour, {left})"; + case "Minute": return $"datepart(minute, {left})"; + case "Second": return $"datepart(second, {left})"; + case "Millisecond": return $"(datepart(millisecond, {left})/1000)"; + case "Ticks": return $"(cast(datediff(second, '1970-1-1', {left}) as bigint)*10000000+621355968000000000)"; + } + return null; + } + public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc) + { + if (exp.Expression == null) + { + switch (exp.Member.Name) + { + case "Zero": return "0"; + case "MinValue": return "-922337203685477580"; //微秒 Ticks / 10 + case "MaxValue": return "922337203685477580"; + } + return null; + } + var left = ExpressionLambdaToSql(exp.Expression, tsc); + switch (exp.Member.Name) + { + case "Days": return $"floor(({left})/{60 * 60 * 24})"; + case "Hours": return $"floor(({left})/{60 * 60}%24)"; + case "Milliseconds": return $"(cast({left} as bigint)*1000)"; + case "Minutes": return $"floor(({left})/60%60)"; + case "Seconds": return $"(({left})%60)"; + case "Ticks": return $"(cast({left} as bigint)*10000000)"; + case "TotalDays": return $"(({left})/{60 * 60 * 24})"; + case "TotalHours": return $"(({left})/{60 * 60})"; + case "TotalMilliseconds": return $"(cast({left} as bigint)*1000)"; + case "TotalMinutes": return $"(({left})/60)"; + case "TotalSeconds": return $"({left})"; + } + return null; + } + + public override string ExpressionLambdaToSqlCallString(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "IsNullOrEmpty": + var arg1 = getExp(exp.Arguments[0]); + return $"({arg1} is null or {arg1} = '')"; + case "IsNullOrWhiteSpace": + var arg2 = getExp(exp.Arguments[0]); + return $"({arg2} is null or {arg2} = '' or ltrim({arg2}) = '')"; + case "Concat": + return _common.StringConcat(exp.Arguments.Select(a => getExp(a)).ToArray(), exp.Arguments.Select(a => a.Type).ToArray()); + case "Format": + if (exp.Arguments[0].NodeType != ExpressionType.Constant) throw new Exception(CoreStrings.Not_Implemented_Expression_ParameterUseConstant(exp,exp.Arguments[0])); + var expArgs0 = ExpressionLambdaToSql(exp.Arguments[0], tsc); + if (exp.Arguments.Count == 1) return expArgs0; + var nchar = expArgs0.StartsWith("N'") ? "N" : ""; + var expArgsHack = exp.Arguments.Count == 2 && exp.Arguments[1].NodeType == ExpressionType.NewArrayInit ? + (exp.Arguments[1] as NewArrayExpression).Expressions : exp.Arguments.Where((a, z) => z > 0); + //3个 {} 时,Arguments 解析出来是分开的 + //4个 {} 时,Arguments[1] 只能解析这个出来,然后里面是 NewArray [] + var expArgs = expArgsHack.Select(a => + { + var atype = (a as UnaryExpression)?.Operand.Type.NullableTypeOrThis() ?? a.Type.NullableTypeOrThis(); + if (atype == typeof(string)) return $"'+{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}+{nchar}'"; + if (atype == typeof(Guid)) return $"'+{_common.IsNull($"cast({ExpressionLambdaToSql(a, tsc)} as char(36))", "''")}+{nchar}'"; + if (atype.IsNumberType()) return $"'+{_common.IsNull($"cast({ExpressionLambdaToSql(a, tsc)} as varchar)", "''")}+{nchar}'"; + return $"'+{_common.IsNull($"cast({ExpressionLambdaToSql(a, tsc)} as nvarchar(max))", "''")}+{nchar}'"; + }).ToArray(); + return string.Format(expArgs0, expArgs); + case "Join": + if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1)) + { + var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod, + Expression.Lambda( + Expression.Call( + typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) }), + Expression.Convert(exp.Arguments[0], typeof(object)), + Expression.Convert(toListArgs1.Body, typeof(object))), + toListArgs1.Parameters)); + var newToListSql = getExp(newToListArgs0); + if (string.IsNullOrEmpty(newToListSql) == false && newToListSql.StartsWith("(") && newToListSql.EndsWith(")")) + { + newToListSql = $"stuff({newToListSql.Substring(0, newToListSql.Length - 1)} FOR XML PATH('')),1,len({getExp(exp.Arguments[0])}),'')"; + return newToListSql; + } + } + break; + } + } + else + { + var left = getExp(exp.Object); + switch (exp.Method.Name) + { + case "StartsWith": + case "EndsWith": + case "Contains": + var args0Value = getExp(exp.Arguments[0]); + if (args0Value == "NULL") return $"({left}) IS NULL"; + if (args0Value.Contains("%")) + { + if (exp.Method.Name == "StartsWith") return $"charindex({args0Value}, {left}) = 1"; + if (exp.Method.Name == "EndsWith") return $"charindex({args0Value}, {left}) = len({args0Value})"; + return $"charindex({args0Value}, {left}) > 0"; + } + if (exp.Method.Name == "StartsWith") return $"({left}) LIKE {(args0Value.EndsWith("'") ? args0Value.Insert(args0Value.Length - 1, "%") : $"(cast({args0Value} as nvarchar(max))+'%')")}"; + if (exp.Method.Name == "EndsWith") return $"({left}) LIKE {(args0Value.StartsWith("'") ? args0Value.Insert(1, "%") : $"('%'+cast({args0Value} as nvarchar(max)))")}"; + if (args0Value.StartsWith("'") && args0Value.EndsWith("'")) return $"({left}) LIKE {args0Value.Insert(1, "%").Insert(args0Value.Length, "%")}"; + return $"({left}) LIKE ('%'+cast({args0Value} as nvarchar(max))+'%')"; + case "ToLower": return $"lower({left})"; + case "ToUpper": return $"upper({left})"; + case "Substring": + var substrArgs1 = getExp(exp.Arguments[0]); + if (long.TryParse(substrArgs1, out var testtrylng1)) substrArgs1 = (testtrylng1 + 1).ToString(); + else substrArgs1 += "+1"; + if (exp.Arguments.Count == 1) return $"left({left}, {substrArgs1})"; + return $"substring({left}, {substrArgs1}, {getExp(exp.Arguments[1])})"; + case "IndexOf": + var indexOfFindStr = getExp(exp.Arguments[0]); + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") + { + var locateArgs1 = getExp(exp.Arguments[1]); + if (long.TryParse(locateArgs1, out var testtrylng2)) locateArgs1 = (testtrylng2 + 1).ToString(); + else locateArgs1 += "+1"; + return $"(charindex({indexOfFindStr}, {left}, {locateArgs1})-1)"; + } + return $"(charindex({indexOfFindStr}, {left})-1)"; + case "PadLeft": + if (exp.Arguments.Count == 1) return $"lpad({left}, {getExp(exp.Arguments[0])})"; + return $"lpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "PadRight": + if (exp.Arguments.Count == 1) return $"rpad({left}, {getExp(exp.Arguments[0])})"; + return $"rpad({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Trim": return $"ltrim(rtrim({left}))"; + case "TrimStart": return $"ltrim({left})"; + case "TrimEnd": return $"rtrim({left})"; + case "Replace": return $"replace({left}, {getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "CompareTo": return $"({left} - {getExp(exp.Arguments[0])})"; + case "Equals": return $"({left} = {getExp(exp.Arguments[0])})"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallMath(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + switch (exp.Method.Name) + { + case "Abs": return $"abs({getExp(exp.Arguments[0])})"; + case "Sign": return $"sign({getExp(exp.Arguments[0])})"; + case "Floor": return $"floor({getExp(exp.Arguments[0])})"; + case "Ceiling": return $"ceiling({getExp(exp.Arguments[0])})"; + case "Round": + if (exp.Arguments.Count > 1 && exp.Arguments[1].Type.FullName == "System.Int32") return $"round({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + return $"round({getExp(exp.Arguments[0])}, 0)"; + case "Exp": return $"exp({getExp(exp.Arguments[0])})"; + case "Log": return $"log({getExp(exp.Arguments[0])})"; + case "Log10": return $"log10({getExp(exp.Arguments[0])})"; + case "Pow": return $"power({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Sqrt": return $"sqrt({getExp(exp.Arguments[0])})"; + case "Cos": return $"cos({getExp(exp.Arguments[0])})"; + case "Sin": return $"sin({getExp(exp.Arguments[0])})"; + case "Tan": return $"tan({getExp(exp.Arguments[0])})"; + case "Acos": return $"acos({getExp(exp.Arguments[0])})"; + case "Asin": return $"asin({getExp(exp.Arguments[0])})"; + case "Atan": return $"atan({getExp(exp.Arguments[0])})"; + case "Atan2": return $"atan2({getExp(exp.Arguments[0])}, {getExp(exp.Arguments[1])})"; + case "Truncate": return $"floor({getExp(exp.Arguments[0])})"; + } + return null; + } + public override string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])} - ({getExp(exp.Arguments[1])}))"; + case "DaysInMonth": return $"datepart(day, dateadd(day, -1, dateadd(month, 1, cast({getExp(exp.Arguments[0])} as varchar(100)) + '-' + cast({getExp(exp.Arguments[1])} as varchar(100)) + '-1')))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + + case "IsLeapYear": + var isLeapYearArgs1 = getExp(exp.Arguments[0]); + return $"(({isLeapYearArgs1})%4=0 AND ({isLeapYearArgs1})%100<>0 OR ({isLeapYearArgs1})%400=0)"; + + case "Parse": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"dateadd(second, {args1}, {left})"; + case "AddDays": return $"dateadd(day, {args1}, {left})"; + case "AddHours": return $"dateadd(hour, {args1}, {left})"; + case "AddMilliseconds": return $"dateadd(second, ({args1})/1000, {left})"; + case "AddMinutes": return $"dateadd(minute, {args1}, {left})"; + case "AddMonths": return $"dateadd(month, {args1}, {left})"; + case "AddSeconds": return $"dateadd(second, {args1}, {left})"; + case "AddTicks": return $"dateadd(second, ({args1})/10000000, {left})"; + case "AddYears": return $"dateadd(year, {args1}, {left})"; + case "Subtract": + switch ((exp.Arguments[0].Type.IsNullableType() ? exp.Arguments[0].Type.GetGenericArguments().FirstOrDefault() : exp.Arguments[0].Type).FullName) + { + case "System.DateTime": return $"datediff(second, {args1}, {left})"; + case "System.TimeSpan": return $"dateadd(second, ({args1})*-1, {left})"; + } + break; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"datediff(second,{args1},{left})"; + case "ToString": + if (left.EndsWith(" as datetime)") == false) left = $"cast({left} as datetime)"; + if (exp.Arguments.Count == 0) return $"convert(varchar, {left}, 121)"; + switch (args1.TrimStart('N')) + { + case "'yyyy-MM-dd HH:mm:ss'": return $"convert(char(19), {left}, 120)"; + case "'yyyy-MM-dd HH:mm'": return $"substring(convert(char(19), {left}, 120), 1, 16)"; + case "'yyyy-MM-dd HH'": return $"substring(convert(char(19), {left}, 120), 1, 13)"; + case "'yyyy-MM-dd'": return $"convert(char(10), {left}, 23)"; + case "'yyyy-MM'": return $"substring(convert(char(10), {left}, 23), 1, 7)"; + case "'yyyyMMdd'": return $"convert(char(8), {left}, 112)"; + case "'yyyyMM'": return $"substring(convert(char(8), {left}, 112), 1, 6)"; + case "'yyyy'": return $"substring(convert(char(8), {left}, 112), 1, 4)"; + case "'HH:mm:ss'": return $"convert(char(8), {left}, 24)"; + } + var isMatched = false; + var nchar = args1.StartsWith("N'") ? "N" : ""; + args1 = Regex.Replace(args1, "(yyyy|yy|MM|M|dd|d|HH|H|hh|h|mm|m|ss|s|tt|t)", m => + { + isMatched = true; + switch (m.Groups[1].Value) + { + case "yyyy": return $"' + substring(convert(char(8), {left}, 112), 1, 4) + {nchar}'"; + case "yy": return $"' + substring(convert(char(6), {left}, 12), 1, 2) + {nchar}'"; + case "MM": return $"' + substring(convert(char(6), {left}, 12), 3, 2) + {nchar}'"; + case "M": return $"' + case when substring(convert(char(6), {left}, 12), 3, 1) = '0' then substring(convert(char(6), {left}, 12), 4, 1) else substring(convert(char(6), {left}, 12), 3, 2) end + {nchar}'"; + case "dd": return $"' + substring(convert(char(6), {left}, 12), 5, 2) + {nchar}'"; + case "d": return $"' + case when substring(convert(char(6), {left}, 12), 5, 1) = '0' then substring(convert(char(6), {left}, 12), 6, 1) else substring(convert(char(6), {left}, 12), 5, 2) end + {nchar}'"; + case "HH": return $"' + substring(convert(char(8), {left}, 24), 1, 2) + {nchar}'"; + case "H": return $"' + case when substring(convert(char(8), {left}, 24), 1, 1) = '0' then substring(convert(char(8), {left}, 24), 2, 1) else substring(convert(char(8), {left}, 24), 1, 2) end + {nchar}'"; + case "hh": + return $"' + case cast(case when substring(convert(char(8), {left}, 24), 1, 1) = '0' then substring(convert(char(8), {left}, 24), 2, 1) else substring(convert(char(8), {left}, 24), 1, 2) end as int) % 12" + + $"when 0 then '12' when 1 then '01' when 2 then '02' when 3 then '03' when 4 then '04' when 5 then '05' when 6 then '06' when 7 then '07' when 8 then '08' when 9 then '09' when 10 then '10' when 11 then '11' end + {nchar}'"; + case "h": + return $"' + case cast(case when substring(convert(char(8), {left}, 24), 1, 1) = '0' then substring(convert(char(8), {left}, 24), 2, 1) else substring(convert(char(8), {left}, 24), 1, 2) end as int) % 12" + + $"when 0 then '12' when 1 then '1' when 2 then '2' when 3 then '3' when 4 then '4' when 5 then '5' when 6 then '6' when 7 then '7' when 8 then '8' when 9 then '9' when 10 then '10' when 11 then '11' end + {nchar}'"; + case "mm": return $"' + substring(convert(char(8), {left}, 24), 4, 2) + {nchar}'"; + case "m": return $"' + case when substring(convert(char(8), {left}, 24), 4, 1) = '0' then substring(convert(char(8), {left}, 24), 5, 1) else substring(convert(char(8), {left}, 24), 4, 2) end + {nchar}'"; + case "ss": return $"' + substring(convert(char(8), {left}, 24), 7, 2) + {nchar}'"; + case "s": return $"' + case when substring(convert(char(8), {left}, 24), 7, 1) = '0' then substring(convert(char(8), {left}, 24), 8, 1) else substring(convert(char(8), {left}, 24), 7, 2) end + {nchar}'"; + case "tt": return $"' + case when cast(case when substring(convert(char(8), {left}, 24), 1, 1) = '0' then substring(convert(char(8), {left}, 24), 2, 1) else substring(convert(char(8), {left}, 24), 1, 2) end as int) >= 12 then 'PM' else 'AM' end + {nchar}'"; + case "t": return $"' + case when cast(case when substring(convert(char(8), {left}, 24), 1, 1) = '0' then substring(convert(char(8), {left}, 24), 2, 1) else substring(convert(char(8), {left}, 24), 1, 2) end as int) >= 12 then 'P' else 'A' end + {nchar}'"; + } + return m.Groups[0].Value; + }); + return isMatched == false ? args1 : $"({args1})"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "Compare": return $"({getExp(exp.Arguments[0])}-({getExp(exp.Arguments[1])}))"; + case "Equals": return $"({getExp(exp.Arguments[0])} = {getExp(exp.Arguments[1])})"; + case "FromDays": return $"(({getExp(exp.Arguments[0])})*{60 * 60 * 24})"; + case "FromHours": return $"(({getExp(exp.Arguments[0])})*{60 * 60})"; + case "FromMilliseconds": return $"(({getExp(exp.Arguments[0])})/1000)"; + case "FromMinutes": return $"(({getExp(exp.Arguments[0])})*60)"; + case "FromSeconds": return $"({getExp(exp.Arguments[0])})"; + case "FromTicks": return $"(({getExp(exp.Arguments[0])})/10000000)"; + case "Parse": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + case "ParseExact": + case "TryParse": + case "TryParseExact": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + } + } + else + { + var left = getExp(exp.Object); + var args1 = exp.Arguments.Count == 0 ? null : getExp(exp.Arguments[0]); + switch (exp.Method.Name) + { + case "Add": return $"({left}+{args1})"; + case "Subtract": return $"({left}-({args1}))"; + case "Equals": return $"({left} = {args1})"; + case "CompareTo": return $"({left}-({args1}))"; + case "ToString": return $"cast({left} as varchar(100))"; + } + } + return null; + } + public override string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, ExpTSC tsc) + { + Func getExp = exparg => ExpressionLambdaToSql(exparg, tsc); + if (exp.Object == null) + { + switch (exp.Method.Name) + { + case "ToBoolean": return $"(cast({getExp(exp.Arguments[0])} as varchar) not in ('0','false'))"; + case "ToByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)"; + case "ToChar": return $"substring(cast({getExp(exp.Arguments[0])} as nvarchar),1,1)"; + case "ToDateTime": return ExpressionConstDateTime(exp.Arguments[0]) ?? $"cast({getExp(exp.Arguments[0])} as datetime)"; + case "ToDecimal": return $"cast({getExp(exp.Arguments[0])} as decimal(36,18))"; + case "ToDouble": return $"cast({getExp(exp.Arguments[0])} as decimal(32,16))"; + case "ToInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)"; + case "ToInt32": return $"cast({getExp(exp.Arguments[0])} as int)"; + case "ToInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + case "ToSByte": return $"cast({getExp(exp.Arguments[0])} as tinyint)"; + case "ToSingle": return $"cast({getExp(exp.Arguments[0])} as decimal(14,7))"; + case "ToString": + var gentype = exp.Arguments[0].Type.NullableTypeOrThis(); + return gentype == typeof(Guid) ? + $"cast({getExp(exp.Arguments[0])} as varchar(36))" : + $"cast({getExp(exp.Arguments[0])} as nvarchar{(gentype.IsNumberType() || gentype.IsEnum ? "(100)" : "(max)")})"; + case "ToUInt16": return $"cast({getExp(exp.Arguments[0])} as smallint)"; + case "ToUInt32": return $"cast({getExp(exp.Arguments[0])} as int)"; + case "ToUInt64": return $"cast({getExp(exp.Arguments[0])} as bigint)"; + } + } + return null; + } + } +} diff --git a/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerProvider.cs b/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerProvider.cs new file mode 100644 index 00000000..e884f3ad --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerProvider.cs @@ -0,0 +1,57 @@ +using FreeSql.Internal.CommonProvider; +using System; +using System.Data.Common; +using System.Threading; + +namespace FreeSql.Custom.SqlServer +{ + + public class CustomSqlServerProvider : BaseDbProvider, IFreeSql + { + public override ISelect CreateSelectProvider(object dywhere) => new CustomSqlServerSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsert CreateInsertProvider() => new CustomSqlServerInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); + public override IUpdate CreateUpdateProvider(object dywhere) => new CustomSqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IDelete CreateDeleteProvider(object dywhere) => new CustomSqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); + public override IInsertOrUpdate CreateInsertOrUpdateProvider() => new CustomSqlServerInsertOrUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression); + + public CustomSqlServerProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) + { + this.InternalCommonUtils = new CustomSqlServerUtils(this); + this.InternalCommonExpression = new CustomSqlServerExpression(this.InternalCommonUtils); + + this.Ado = new CustomSqlServerAdo(this.InternalCommonUtils, masterConnectionString, slaveConnectionString, connectionFactory); + this.Aop = new AopProvider(); + + this.DbFirst = new CustomSqlServerDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + this.CodeFirst = new CustomSqlServerCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); + + if (this.Ado.MasterPool != null) + try + { + using (var conn = this.Ado.MasterPool.Get()) + { + (this.InternalCommonUtils as CustomSqlServerUtils).ServerVersion = int.Parse(conn.Value.ServerVersion.Split('.')[0]); + } + } + catch + { + } + } + + ~CustomSqlServerProvider() => this.Dispose(); + int _disposeCounter; + public override void Dispose() + { + if (Interlocked.Increment(ref _disposeCounter) != 1) return; + try + { + (this.Ado as AdoProvider)?.Dispose(); + } + finally + { + FreeSqlCustomAdapterGlobalExtensions._dicCustomAdater.TryRemove(Ado.Identifier, out var tryada); + FreeSqlCustomAdapterGlobalExtensions._dicDbProviderFactory.TryRemove(Ado.Identifier, out var trydbpf); + } + } + } +} diff --git a/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerUtils.cs b/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerUtils.cs new file mode 100644 index 00000000..0a78ff34 --- /dev/null +++ b/Providers/FreeSql.Provider.Custom/SqlServer/CustomSqlServerUtils.cs @@ -0,0 +1,109 @@ +using FreeSql.Internal; +using FreeSql.Internal.CommonProvider; +using FreeSql.Internal.Model; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Common; +using System.Globalization; +using System.Text; + +namespace FreeSql.Custom.SqlServer +{ + + public class CustomSqlServerUtils : CommonUtils + { + DbProviderFactory Factory => FreeSqlCustomAdapterGlobalExtensions.GetDbProviderFactory(_orm); + + public CustomSqlServerUtils(IFreeSql orm) : base(orm) + { + } + + public bool IsSelectRowNumber => ServerVersion <= 10; + public bool IsSqlServer2005 => ServerVersion == 9; + public int ServerVersion = 0; + + public override DbParameter AppendParamter(List _params, string parameterName, ColumnInfo col, Type type, object value) + { + if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; + if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); + var ret = Factory.CreateParameter(); + ret.ParameterName = QuoteParamterName(parameterName); + ret.Value = value; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.DbType = (DbType)tp.Value; + _params?.Add(ret); + return ret; + } + + public override DbParameter[] GetDbParamtersByObject(string sql, object obj) => + Utils.GetDbParamtersByObject(sql, obj, null, (name, type, value) => + { + if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); + var ret = Factory.CreateParameter(); + ret.ParameterName = $"@{name}"; + ret.Value = value; + var tp = _orm.CodeFirst.GetDbInfo(type)?.type; + if (tp != null) ret.DbType = (DbType)tp.Value; + return ret; + }); + + public override string FormatSql(string sql, params object[] args) => sql?.FormatCustomSqlServer(args); + public override string QuoteSqlName(params string[] name) + { + if (name.Length == 1) + { + var nametrim = name[0].Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + if (nametrim.StartsWith("[") && nametrim.EndsWith("]")) + return nametrim; + return $"[{nametrim.Replace(".", "].[")}]"; + } + return $"[{string.Join("].[", name)}]"; + } + public override string TrimQuoteSqlName(string name) + { + var nametrim = name.Trim(); + if (nametrim.StartsWith("(") && nametrim.EndsWith(")")) + return nametrim; //原生SQL + return $"{nametrim.TrimStart('[').TrimEnd(']').Replace("].[", ".").Replace(".[", ".")}"; + } + public override string[] SplitTableName(string name) => GetSplitTableNames(name, '[', ']', 3); + public override string QuoteParamterName(string name) => $"@{name}"; + public override string IsNull(string sql, object value) => $"isnull({sql}, {value})"; + public override string StringConcat(string[] objs, Type[] types) + { + var sb = new StringBuilder(); + var news = new string[objs.Length]; + for (var a = 0; a < objs.Length; a++) + { + if (types[a] == typeof(string)) news[a] = objs[a]; + else if (types[a].NullableTypeOrThis() == typeof(Guid)) news[a] = $"cast({objs[a]} as char(36))"; + else if (types[a].IsNumberType()) news[a] = $"cast({objs[a]} as varchar)"; + else news[a] = $"cast({objs[a]} as nvarchar(max))"; + } + return string.Join(" + ", news); + } + public override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; + public override string Div(string left, string right, Type leftType, Type rightType) => $"{left} / {right}"; + public override string Now => "getdate()"; + public override string NowUtc => "getutcdate()"; + + public override string QuoteWriteParamterAdapter(Type type, string paramterName) => paramterName; + protected override string QuoteReadColumnAdapter(Type type, Type mapType, string columnName) => columnName; + + public override string GetNoneParamaterSqlValue(List specialParams, string specialParamFlag, ColumnInfo col, Type type, object value) + { + if (value == null) return "NULL"; + if (type.IsNumberType()) return string.Format(CultureInfo.InvariantCulture, "{0}", value); + if (type == typeof(byte[])) return $"0x{CommonUtils.BytesSqlRaw(value as byte[])}"; + if (type == typeof(TimeSpan) || type == typeof(TimeSpan?)) + { + var ts = (TimeSpan)value; + value = $"{ts.Hours}:{ts.Minutes}:{ts.Seconds}.{ts.Milliseconds}"; + } + return string.Format(CultureInfo.InvariantCulture, "{0}", (_orm.Ado as AdoProvider).AddslashesProcessParam(value, type, col)); + } + } +} diff --git a/Providers/FreeSql.Provider.Custom/readme.md b/Providers/FreeSql.Provider.Custom/readme.md index e436089d..b4d63693 100644 --- a/Providers/FreeSql.Provider.Custom/readme.md +++ b/Providers/FreeSql.Provider.Custom/readme.md @@ -1,8 +1,39 @@ -FreeSql.Provider.Custom 实现自定义适配器,访问所有数据库。 +# 国产数据库 -# 通用实现 +| 数据库名称 | 提供者 | 系列风格 | +| --- | --- | --- | +| 达梦 | FreeSql.Provider.Dameng | Oracle | +| 神州通用 | FreeSql.Provider.ShenTong | PostgreSQL | +| 人大金仓 | FreeSql.Provider.KingbaseES | PostgreSQL | +| 南大通用 | FreeSql.Provider.GBase | Informix | +| 翰高 | FreeSql.Provider.Custom、FreeSql.Provider.Odbc | PostgreSQL | -通用实现为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库,牺牲了一些功能: +由于太多,在此不一一列举,它们大多数有共同特点:语法兼容 MySql、Oracle、SqlServer、PostgreSQL 四种常用数据库,FreeSql.Provider.Custom 提供了这四种数据库适配,并且支持 CodeFirst/DbFirst 以及完整的 FreeSql 功能。 + +FreeSql.Provider.Custom 不依赖具体 ado.net/odbc/oledb dll 驱动,使用者在外部自行引用 dll 驱动。 + +访问 MySql 数据库为例: + +```csharp +var fsql = new FreeSqlBuilder() + .UseConnectionFactory(DataType.CustomMySql, () => + new MySqlConnection("Data Source=...")) + .UseNoneParameter(true) + .UseMonitorCommand(Console.WriteLine(cmd.CommandText)) + .Build(); +fsql.SetDbProviderFactory(MySqlConnectorFactory.Instance); +``` + +若某国产数据库兼容 MySql SQL,先引用对方提供的 DLL,然后: + +- 将上面 new MySqlConnection 替换成 new XxxConnection +- 将上面 MySqlConnectorFactory.Instance 替换成对应的 DbProviderFactory + +提示:对方 DLL 一般都会提供这两个现实类 + +# 自定义适配 + +为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库,牺牲了一些功能: - 不支持 CodeFirst 自动迁移 - 不支持 DbFirst 接口方法的实现 @@ -20,8 +51,8 @@ class Mssql2000Adapter : FreeSql.Custom.CustomAdapter //可以重写更多的设置 } -static IFreeSql fsql = new FreeSql.FreeSqlBuilder() - .UseConnectionString(FreeSql.DataType.Custom, () => new SqlConnection(@"Data Source=...")) +static IFreeSql fsql = new FreeSqlBuilder() + .UseConnectionString(DataType.Custom, () => new SqlConnection(@"Data Source=...")) .Build(); //be sure to define as singleton mode fsql.SetCustomAdapter(new Mssql2000Adapter()); diff --git a/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs b/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs index bc998ccf..3f91fbbc 100644 --- a/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs +++ b/Providers/FreeSql.Provider.Odbc/FreeSqlOdbcGlobalExtensions.cs @@ -7,7 +7,7 @@ /// /// /// - public static string FormatOdbcOracle(this string that, params object[] args) => _odbcOracleAdo.Addslashes(that, args); + internal static string FormatOdbcOracle(this string that, params object[] args) => _odbcOracleAdo.Addslashes(that, args); static FreeSql.Odbc.Oracle.OdbcOracleAdo _odbcOracleAdo = new FreeSql.Odbc.Oracle.OdbcOracleAdo(); /// @@ -16,7 +16,7 @@ /// /// /// - public static string FormatOdbcSqlServer(this string that, params object[] args) => _odbcSqlServerAdo.Addslashes(that, args); + internal static string FormatOdbcSqlServer(this string that, params object[] args) => _odbcSqlServerAdo.Addslashes(that, args); static FreeSql.Odbc.SqlServer.OdbcSqlServerAdo _odbcSqlServerAdo = new FreeSql.Odbc.SqlServer.OdbcSqlServerAdo(); /// @@ -25,7 +25,7 @@ /// /// /// - public static string FormatOdbcMySql(this string that, params object[] args) => _odbcMySqlAdo.Addslashes(that, args); + internal static string FormatOdbcMySql(this string that, params object[] args) => _odbcMySqlAdo.Addslashes(that, args); static FreeSql.Odbc.MySql.OdbcMySqlAdo _odbcMySqlAdo = new FreeSql.Odbc.MySql.OdbcMySqlAdo(); /// @@ -34,7 +34,7 @@ /// /// /// - public static string FormatOdbcPostgreSQL(this string that, params object[] args) => _odbcPostgreSQLAdo.Addslashes(that, args); + internal static string FormatOdbcPostgreSQL(this string that, params object[] args) => _odbcPostgreSQLAdo.Addslashes(that, args); static FreeSql.Odbc.PostgreSQL.OdbcPostgreSQLAdo _odbcPostgreSQLAdo = new FreeSql.Odbc.PostgreSQL.OdbcPostgreSQLAdo(); /// @@ -43,7 +43,7 @@ /// /// /// - public static string FormatOdbc(this string that, params object[] args) => _odbcAdo.Addslashes(that, args); + internal static string FormatOdbc(this string that, params object[] args) => _odbcAdo.Addslashes(that, args); static FreeSql.Odbc.Default.OdbcAdo _odbcAdo = new FreeSql.Odbc.Default.OdbcAdo(); /// @@ -52,7 +52,7 @@ /// /// /// - public static string FormatOdbcDameng(this string that, params object[] args) => _odbcDamengAdo.Addslashes(that, args); + internal static string FormatOdbcDameng(this string that, params object[] args) => _odbcDamengAdo.Addslashes(that, args); static FreeSql.Odbc.Dameng.OdbcDamengAdo _odbcDamengAdo = new FreeSql.Odbc.Dameng.OdbcDamengAdo(); /// @@ -61,6 +61,6 @@ /// /// /// - public static string FormatOdbcKingbaseES(this string that, params object[] args) => _odbcKingbaseESAdo.Addslashes(that, args); + internal static string FormatOdbcKingbaseES(this string that, params object[] args) => _odbcKingbaseESAdo.Addslashes(that, args); static FreeSql.Odbc.KingbaseES.OdbcKingbaseESAdo _odbcKingbaseESAdo = new FreeSql.Odbc.KingbaseES.OdbcKingbaseESAdo(); } diff --git a/Providers/FreeSql.Provider.Odbc/readme.md b/Providers/FreeSql.Provider.Odbc/readme.md index dc698f7c..0e9e0c3a 100644 --- a/Providers/FreeSql.Provider.Odbc/readme.md +++ b/Providers/FreeSql.Provider.Odbc/readme.md @@ -1,12 +1,14 @@ FreeSql.Provider.Odbc 实现 ODBC 访问数据库,ODBC 属于比较原始的技术,更新慢,各大数据库厂支持得标准不一,不到万不得已最好别用 odbc,坑比较多。 -FreeSql.Provider.Odbc 做了四种数据库的专用实现:SqlServer、PostgreSQL、Oracle、MySql、达梦、人大金仓,和一种通用实现。 +FreeSql.Provider.Odbc 做了多种数据库的专用实现:SqlServer、PostgreSQL、Oracle、MySql、达梦、人大金仓,和一种通用实现。 -专用实现比较有针对性,和原来的 FreeSql.Provider.SqlServer ado.net 相比,只支持较少的基础类型,其他功能几乎都有,包括 CodeFirst 自动迁移。 +和原来的 FreeSql.Provider.SqlServer 等 ado.net 相比,只支持较少的基础类型,其他功能几乎都有,包括 CodeFirst 自动迁移。 -# 通用实现 +国产数据库大多数都兼容 SqlServer、PostgreSQL、Oracle、MySql 这四种数据库,所以它们也可以用来访问国产数据库。 -通用实现为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库,牺牲了一些功能: +# 自定义适配 + +为了让用户自己适配更多的数据库,比如连接 mssql 2000、db2 等数据库,牺牲了一些功能: - 不支持 CodeFirst 自动迁移 - 不支持 DbFirst 接口方法的实现