diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..857a5990a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,22 @@ +# Top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 4 +tab_width = 4 +trim_trailing_whitespace = true +insert_final_newline = true +end_of_line = lf + +[*.{csproj,props,build}] +indent_size = 2 + +[*.{cs,vb}] +# Organize usings +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = true + +[*.cs] +# CS1574: XML comment has cref attribute that could not be resolved +dotnet_diagnostic.CS1574.severity = none diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml new file mode 100644 index 000000000..929a55029 --- /dev/null +++ b/.github/workflows/build-pr.yml @@ -0,0 +1,69 @@ +name: Build & Run Tests for PR +on: + pull_request: + +env: + REPODB_SQLSERVER_CONSTR_MASTER: "Server=tcp:127.0.0.1,41433;Database=master;User ID=sa;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;TrustServerCertificate=True;" + REPODB_SQLSERVER_CONSTR_REPODB: "Server=tcp:127.0.0.1,41433;Database=RepoDb;User ID=sa;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;TrustServerCertificate=True;" + REPODB_SQLSERVER_CONSTR_REPODBTEST: "Server=tcp:127.0.0.1,41433;Database=RepoDbTest;User ID=sa;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;TrustServerCertificate=True;" + REPODB_POSTGRESQL_CONSTR_POSTGRESDB: "Server=127.0.0.1;Port=45432;Database=postgres;User Id=postgres;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" + REPODB_POSTGRESQL_CONSTR: "Server=127.0.0.1;Port=45432;Database=RepoDb;User Id=postgres;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" + REPODB_POSTGRESQL_CONSTR_BULK: "Server=127.0.0.1;Port=45432;Database=RepoDbBulk;User Id=postgres;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" + REPODB_MYSQL_CONSTR_SYS: "Server=127.0.0.1;Port=43306;Database=sys;User ID=root;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" + REPODB_MYSQL_CONSTR_REPODB: "Server=127.0.0.1;Port=43306;Database=RepoDb;User ID=root;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" + REPODB_MYSQL_CONSTR_REPODBTEST: "Server=127.0.0.1;Port=43306;Database=RepoDbTest;User ID=root;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" + +jobs: + build: + runs-on: ubuntu-latest + + # Services. See docker-compose.yml + services: + mssql: + image: mcr.microsoft.com/mssql/server:2022-latest + ports: + - 127.0.0.1:41433:1433 + env: + ACCEPT_EULA: true + MSSQL_SA_PASSWORD: ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2 + + postgresql: + image: postgres:latest + ports: + - 127.0.0.1:45432:5432 + env: + POSTGRES_PASSWORD: ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2 + + mysql: + image: mysql:latest + ports: + - 127.0.0.1:43306:3306 + env: + MYSQL_ROOT_PASSWORD: ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2 + + steps: + - name: Check out repository code + uses: actions/checkout@v4 + + - name: Setup .NET Versions + uses: actions/setup-dotnet@v4 + with: + dotnet-version: | + 6.0.x + 7.0.x + 8.0.x + + - name: build + run: dotnet build -c release + + - name: test + run: dotnet test -c release -f net8.0 --no-build -p:TestingPlatformShowTestsFailure=true -p:TestingPlatformCaptureOutput=false + + - name: pack packages + run: dotnet pack -c release -p Version="1.14.0-dev-pr-${{ github.run_number }}" -o release RepoDb.Core/RepoDb.All.sln + + - name: Package nupkg files + uses: actions/upload-artifact@v3 + with: + name: release + path: release/*nupkg diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..cef059433 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,69 @@ +name: Build & Run Tests (Push) +on: + push + +env: + REPODB_SQLSERVER_CONSTR_MASTER: "Server=tcp:127.0.0.1,41433;Database=master;User ID=sa;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;TrustServerCertificate=True;" + REPODB_SQLSERVER_CONSTR_REPODB: "Server=tcp:127.0.0.1,41433;Database=RepoDb;User ID=sa;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;TrustServerCertificate=True;" + REPODB_SQLSERVER_CONSTR_REPODBTEST: "Server=tcp:127.0.0.1,41433;Database=RepoDbTest;User ID=sa;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;TrustServerCertificate=True;" + REPODB_POSTGRESQL_CONSTR_POSTGRESDB: "Server=127.0.0.1;Port=45432;Database=postgres;User Id=postgres;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" + REPODB_POSTGRESQL_CONSTR: "Server=127.0.0.1;Port=45432;Database=RepoDb;User Id=postgres;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" + REPODB_POSTGRESQL_CONSTR_BULK: "Server=127.0.0.1;Port=45432;Database=RepoDbBulk;User Id=postgres;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" + REPODB_MYSQL_CONSTR_SYS: "Server=127.0.0.1;Port=43306;Database=sys;User ID=root;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" + REPODB_MYSQL_CONSTR_REPODB: "Server=127.0.0.1;Port=43306;Database=RepoDb;User ID=root;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" + REPODB_MYSQL_CONSTR_REPODBTEST: "Server=127.0.0.1;Port=43306;Database=RepoDbTest;User ID=root;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" + +jobs: + build: + runs-on: ubuntu-latest + + # Services. See docker-compose.yml + services: + mssql: + image: mcr.microsoft.com/mssql/server:2022-latest + ports: + - 127.0.0.1:41433:1433 + env: + ACCEPT_EULA: true + MSSQL_SA_PASSWORD: ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2 + + postgresql: + image: postgres:latest + ports: + - 127.0.0.1:45432:5432 + env: + POSTGRES_PASSWORD: ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2 + + mysql: + image: mysql:latest + ports: + - 127.0.0.1:43306:3306 + env: + MYSQL_ROOT_PASSWORD: ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2 + + steps: + - name: Check out repository code + uses: actions/checkout@v4 + + - name: Setup .NET Versions + uses: actions/setup-dotnet@v4 + with: + dotnet-version: | + 6.0.x + 7.0.x + 8.0.x + + - name: build + run: dotnet build -c release RepoDb.Core/RepoDb.All.sln + + - name: test for .Net 8.0 + run: dotnet test -c release -f net8.0 --no-build -p:TestingPlatformShowTestsFailure=true -p:TestingPlatformCaptureOutput=false RepoDb.Core/RepoDb.All.sln + + - name: pack packages + run: dotnet pack -c release -p Version="1.14.0-dev-${{ github.run_number }}" -o release RepoDb.Core/RepoDb.All.sln + + - name: Package nupkg files + uses: actions/upload-artifact@v3 + with: + name: release + path: release/*nupkg diff --git a/Directory.Build.props b/Directory.Build.props index fc92cd4ad..d115e6210 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,13 +1,28 @@ - Michael Camara Pendon + Michael Camara Pendon and others RepoDb RepoDb + 0.0.1-dev default - Copyright © 2020 + Copyright © 2020-2024 https://repodb.net/ Github LICENSE.txt + README.md + true + true + portable + true + annotations + true + true - \ No newline at end of file + + + + true + + + diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 000000000..0b5b6f38d --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,43 @@ + + + true + true + $(NoWarn);NU1507 + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RepoDb.Benchmarks/RepoDb.Benchmarks.PostgreSql/RepoDb.Benchmarks.PostgreSql.csproj b/RepoDb.Benchmarks/RepoDb.Benchmarks.PostgreSql/RepoDb.Benchmarks.PostgreSql.csproj index 497feb51c..3f7703a5d 100644 --- a/RepoDb.Benchmarks/RepoDb.Benchmarks.PostgreSql/RepoDb.Benchmarks.PostgreSql.csproj +++ b/RepoDb.Benchmarks/RepoDb.Benchmarks.PostgreSql/RepoDb.Benchmarks.PostgreSql.csproj @@ -1,24 +1,21 @@  - Exe net6.0;net7.0;net8.0 + false - - - - - - - - - - + + + + + + + + + - - - + \ No newline at end of file diff --git a/RepoDb.Benchmarks/RepoDb.Benchmarks.SqlServer/RepoDb.Benchmarks.SqlServer.csproj b/RepoDb.Benchmarks/RepoDb.Benchmarks.SqlServer/RepoDb.Benchmarks.SqlServer.csproj index 357b438bb..935276dba 100644 --- a/RepoDb.Benchmarks/RepoDb.Benchmarks.SqlServer/RepoDb.Benchmarks.SqlServer.csproj +++ b/RepoDb.Benchmarks/RepoDb.Benchmarks.SqlServer/RepoDb.Benchmarks.SqlServer.csproj @@ -1,24 +1,21 @@  - Exe net6.0;net7.0;net8.0 + false - - - - - - - - + + + + + + + - - - + \ No newline at end of file diff --git a/RepoDb.Core/.editorconfig b/RepoDb.Core/.editorconfig deleted file mode 100644 index 16cd8ca45..000000000 --- a/RepoDb.Core/.editorconfig +++ /dev/null @@ -1,4 +0,0 @@ -[*.cs] - -# CS1574: XML comment has cref attribute that could not be resolved -dotnet_diagnostic.CS1574.severity = none diff --git a/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/BaseEnferredInheritanceTest.cs b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/BaseEnferredInheritanceTest.cs index 1eca2b7b3..19c7e2e2e 100644 --- a/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/BaseEnferredInheritanceTest.cs +++ b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/BaseEnferredInheritanceTest.cs @@ -1,6 +1,6 @@ using System; -using Microsoft.Data.SqlClient; using System.Linq; +using Microsoft.Data.SqlClient; using Microsoft.VisualStudio.TestTools.UnitTesting; using RepoDb.IntegrationTests.Models; using RepoDb.IntegrationTests.Setup; @@ -100,6 +100,7 @@ public void TestSqlConnectionInsertForInherited() public void TestSqlConnectionInsertAllForInherited() { // Setup + // warning CA2021: This call will always result in an empty sequence because type 'RepoDb.IntegrationTests.Models.InheritedIdentityTable' is incompatible with type 'RepoDb.IntegrationTests.Models.Entity' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2021) var entities = Helper.CreateInheritedIdentityTables(10) .OfType>().ToList(); @@ -192,6 +193,7 @@ public void TestSqlConnectionMergeForInheritedWithNonEmptyTable() public void TestSqlConnectionMergeAllForInherited() { // Setup + // warning CA2021: This call will always result in an empty sequence because type 'RepoDb.IntegrationTests.Models.InheritedIdentityTable' is incompatible with type 'RepoDb.IntegrationTests.Models.Entity' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2021) var entities = Helper.CreateInheritedIdentityTables(10) .OfType>().ToList(); @@ -217,6 +219,7 @@ public void TestSqlConnectionMergeAllForInherited() public void TestSqlConnectionMergeAllForInheritedWithNonEmptyTables() { // Setup + // warning CA2021: This call will always result in an empty sequence because type 'RepoDb.IntegrationTests.Models.InheritedIdentityTable' is incompatible with type 'RepoDb.IntegrationTests.Models.Entity' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2021) var entities = Helper.CreateInheritedIdentityTables(10) .OfType>().ToList(); @@ -344,6 +347,7 @@ public void TestSqlConnectionUpdateForInheritedViaPrimaryKey() public void TestSqlConnectionUpdateAllForInherited() { // Setup + // warning CA2021: This call will always result in an empty sequence because type 'RepoDb.IntegrationTests.Models.InheritedIdentityTable' is incompatible with type 'RepoDb.IntegrationTests.Models.Entity' (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2021) var entities = Helper.CreateInheritedIdentityTables(10) .OfType>().ToList(); diff --git a/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/CultureScope.cs b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/CultureScope.cs index 1233373c2..bd733eeaf 100644 --- a/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/CultureScope.cs +++ b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/CultureScope.cs @@ -1,7 +1,5 @@ using System; -using System.Collections.Generic; using System.Globalization; -using System.Text; namespace RepoDb.IntegrationTests { @@ -11,16 +9,20 @@ namespace RepoDb.IntegrationTests /// internal sealed class CultureScope : IDisposable { - private readonly CultureInfo original; + private readonly CultureInfo originalCulture; + private readonly CultureInfo originalUICulture; + public CultureScope(string cultureName) { - original = CultureInfo.DefaultThreadCurrentCulture; - CultureInfo.DefaultThreadCurrentCulture = CultureInfo.GetCultureInfo(cultureName); + originalCulture = CultureInfo.CurrentCulture; + originalUICulture = CultureInfo.CurrentUICulture; + CultureInfo.CurrentUICulture = CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo(cultureName); } public void Dispose() { - CultureInfo.DefaultThreadCurrentCulture = original; + CultureInfo.CurrentUICulture = originalUICulture; + CultureInfo.CurrentCulture = originalCulture; } } } diff --git a/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/RepoDb.IntegrationTests.csproj b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/RepoDb.IntegrationTests.csproj index 4792bb95b..905740377 100644 --- a/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/RepoDb.IntegrationTests.csproj +++ b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/RepoDb.IntegrationTests.csproj @@ -1,10 +1,11 @@  - net6.0;net7.0;net8.0 false + true + true + true - @@ -25,24 +26,18 @@ - - - - - - + + - - - + \ No newline at end of file diff --git a/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/Setup/Database.cs b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/Setup/Database.cs index 2805933c3..52fcc92fd 100644 --- a/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/Setup/Database.cs +++ b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/Setup/Database.cs @@ -13,15 +13,19 @@ public static class Database /// public static void Initialize() { - // Get the connection string - var connectionStringForMaster = Environment.GetEnvironmentVariable("REPODB_CONSTR_MASTER", EnvironmentVariableTarget.Process); - var connectionString = Environment.GetEnvironmentVariable("REPODB_CONSTR", EnvironmentVariableTarget.Process); - // Master connection - ConnectionStringForMaster = (connectionStringForMaster ?? @"Server=(local);Database=master;Integrated Security=SSPI;TrustServerCertificate=True;"); + ConnectionStringForMaster = + Environment.GetEnvironmentVariable("REPODB_SQLSERVER_CONSTR_MASTER") + ?? Environment.GetEnvironmentVariable("REPODB_CONSTR_MASTER") + // ?? "Server=tcp:127.0.0.1,41433;Database=master;User ID=sa;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;TrustServerCertificate=True;" // Docker test configuration + ?? "Server=(local);Database=master;Integrated Security=SSPI;TrustServerCertificate=True;"; // RepoDb connection - ConnectionStringForRepoDb = (connectionString ?? @"Server=(local);Database=RepoDb;Integrated Security=SSPI;TrustServerCertificate=True;"); + ConnectionStringForRepoDb = + Environment.GetEnvironmentVariable("REPODB_SQLSERVER_CONSTR_REPODB") + ?? Environment.GetEnvironmentVariable("REPODB_CONSTR") + // ?? "Server=tcp:127.0.0.1,41433;Database=RepoDb;User ID=sa;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;TrustServerCertificate=True;" // Docker test configuration + ?? "Server=(local);Database=RepoDb;Integrated Security=SSPI;TrustServerCertificate=True;"; // Set the proper values for type mapper TypeMapper.Add(typeof(DateTime), System.Data.DbType.DateTime2, true); diff --git a/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/TypeConversionsTest.cs b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/TypeConversionsTest.cs index ba80999e6..2c5c91cd6 100644 --- a/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/TypeConversionsTest.cs +++ b/RepoDb.Core/RepoDb.Tests/RepoDb.IntegrationTests/TypeConversionsTest.cs @@ -1,10 +1,11 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.ComponentModel; +using System.Linq; +using Microsoft.Data.SqlClient; +using Microsoft.VisualStudio.TestTools.UnitTesting; using RepoDb.Attributes; using RepoDb.Enumerations; using RepoDb.IntegrationTests.Setup; -using System; -using Microsoft.Data.SqlClient; -using System.Linq; namespace RepoDb.IntegrationTests { @@ -134,6 +135,7 @@ public void TestSqlConnectionExecuteQueryConversionFromStringToBit() [TestMethod] public void TestSqlConnectionExecuteQueryConversionFromStringToDecimal() { + using var _ = new CultureScope("EN-US"); using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb).EnsureOpen()) { // Act Query @@ -147,6 +149,7 @@ public void TestSqlConnectionExecuteQueryConversionFromStringToDecimal() [TestMethod] public void TestSqlConnectionExecuteQueryConversionFromStringToFloat() { + using var _ = new CultureScope("EN-US"); using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb).EnsureOpen()) { // Act Query @@ -263,6 +266,7 @@ public void TestSqlConnectionExecuteQueryConversionFromDecimalToDecimal() [TestMethod] public void TestSqlConnectionExecuteQueryConversionFromDecimalToString() { + using var _ = new CultureScope("EN-US"); using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb).EnsureOpen()) { // Act Query @@ -306,6 +310,7 @@ public void TestSqlConnectionExecuteQueryConversionFromRealToFloat() [TestMethod] public void TestSqlConnectionExecuteQueryConversionFromRealToString() { + using var _ = new CultureScope("EN-US"); using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb).EnsureOpen()) { // Act Query @@ -424,6 +429,298 @@ public void TestSqlConnectionExecuteQueryConversionFromBitToString() #endregion + + enum Direction + { + None, + North, + East, + South, + West + } + enum Direction2 + { + None, + North, + East, + South, + West + } + + enum Direction3 + { + None, + North, + East, + South, + West + } + + enum Direction4 + { + None, + North, + East, + South, + West + } + + [TestMethod] + public void TestSqlConnectionExecuteQueryConversionFromIntToEnum() + { + using var _ = new CultureScope("EN-US"); + + // With automatic conversion + using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb).EnsureOpen()) + { + // Act Query + var data = connection.ExecuteQuery("SELECT CONVERT(INT, 1) AS Value;").First(); + var data0 = connection.ExecuteQuery("SELECT CONVERT(INT, 0) AS Value;").First(); + var data10 = connection.ExecuteQuery("SELECT CONVERT(INT, 10) AS Value;").First(); + + // Assert + Assert.AreEqual(Direction.North, data); + Assert.AreEqual(Direction.None, data0); + Assert.AreEqual((Direction)10, data10); + } + + GlobalConfiguration.Setup(new() { ConversionType = ConversionType.Default, EnumHandling = EnumHandling.UseDefault }); + + // With default conversion + using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb).EnsureOpen()) + { + // Act Query + var data = connection.ExecuteQuery("SELECT CONVERT(INT, 1) AS Value;").First(); + var data0 = connection.ExecuteQuery("SELECT CONVERT(INT, 0) AS Value;").First(); + var data10 = connection.ExecuteQuery("SELECT CONVERT(INT, 10) AS Value;").First(); + + // Assert + Assert.AreEqual(Direction2.North, data); + Assert.AreEqual(Direction2.None, data0); + Assert.AreEqual(Direction2.None, data10); + } + + + GlobalConfiguration.Setup(new() { ConversionType = ConversionType.Default, EnumHandling = EnumHandling.ThrowError }); + + // With default conversion + using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb).EnsureOpen()) + { + // Act Query + var data = connection.ExecuteQuery("SELECT CONVERT(INT, 1) AS Value;").First(); + var data0 = connection.ExecuteQuery("SELECT CONVERT(INT, 0) AS Value;").First(); + + // Assert + Assert.AreEqual(Direction3.North, data); + Assert.AreEqual(Direction3.None, data0); + + try + { + var data10 = connection.ExecuteQuery("SELECT CONVERT(INT, 10) AS Value;").First(); + Assert.Fail("Should have failed"); + } + catch (InvalidEnumArgumentException e) + { + Assert.IsTrue(e.Message.Contains(nameof(Direction3))); + + // We are in an EN-US scope so the message should match + Assert.AreEqual("The value of argument 'value' (10) is invalid for Enum type 'Direction3'. (Parameter 'value')", e.Message); + } + } + } + + [TestMethod] + public void TestSqlConnectionExecuteQueryConversionFromStringToEnum() + { + using var _ = new CultureScope("EN-US"); + + // With automatic conversion + using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb).EnsureOpen()) + { + // Act Query + var data = connection.ExecuteQuery("SELECT 'North' AS Value;").First(); + var data0 = connection.ExecuteQuery("SELECT 'None' AS Value;").First(); + var data3 = connection.ExecuteQuery("SELECT '3' AS Value;").First(); + var data9 = connection.ExecuteQuery("SELECT '9' AS Value;").First(); + try + { + var data10 = connection.ExecuteQuery("SELECT 'Center' AS Value;").First(); + Assert.Fail("Should have failed Direction/3"); + } + catch (ArgumentOutOfRangeException e) + { + Assert.IsTrue(e.Message.Contains(nameof(Direction))); + + // We are in an EN-US scope so the message should match + Assert.AreEqual("Invalid value for Direction (Parameter 'value')\nActual value was Center.", e.Message.Replace("\r", "")); + } + + // Assert + Assert.AreEqual(Direction.North, data); + Assert.AreEqual(Direction.South, data3); + Assert.AreEqual(Direction.None, data0); + Assert.AreEqual((Direction)9, data9); + } + + GlobalConfiguration.Setup(new() { ConversionType = ConversionType.Default, EnumHandling = EnumHandling.UseDefault }); + + // With default conversion + using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb).EnsureOpen()) + { + // Act Query + var data = connection.ExecuteQuery("SELECT 'North' AS Value;").First(); + var data0 = connection.ExecuteQuery("SELECT 'None' AS Value;").First(); + var data3 = connection.ExecuteQuery("SELECT '3' AS Value;").First(); + var data9 = connection.ExecuteQuery("SELECT '9' AS Value;").First(); + var data10 = connection.ExecuteQuery("SELECT 'Center' AS Value;").First(); + + // Assert + Assert.AreEqual(Direction2.North, data); + Assert.AreEqual(Direction2.None, data0); + Assert.AreEqual(Direction2.South, data3); + Assert.AreEqual(Direction2.None, data9); + Assert.AreEqual(Direction2.None, data10); + } + + + GlobalConfiguration.Setup(new() { ConversionType = ConversionType.Default, EnumHandling = EnumHandling.ThrowError }); + + // With default conversion + using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb).EnsureOpen()) + { + // Act Query + var data = connection.ExecuteQuery("SELECT 'North' AS Value;").First(); + var data0 = connection.ExecuteQuery("SELECT 'None' AS Value;").First(); + + try + { + var data10 = connection.ExecuteQuery("SELECT 'Center' AS Value;").First(); + Assert.Fail("Should have failed Direction3/Center"); + } + catch (ArgumentOutOfRangeException e) + { + Assert.IsTrue(e.Message.Contains(nameof(Direction3))); + + // We are in an EN-US scope so the message should match + Assert.AreEqual("Invalid value for Direction3 (Parameter 'value')\nActual value was Center.", e.Message.Replace("\r", "")); + } + + try + { + var data9 = connection.ExecuteQuery("SELECT '9' AS Value;").First(); + Assert.Fail("Should have failed Direction3/9"); + } + catch (ArgumentOutOfRangeException e) + { + Assert.IsTrue(e.Message.Contains(nameof(Direction3))); + + // We are in an EN-US scope so the message should match + Assert.AreEqual("Invalid value for Direction3 (Parameter 'value')\nActual value was 9.", e.Message.Replace("\r", "")); + } + + // Assert + Assert.AreEqual(Direction3.North, data); + Assert.AreEqual(Direction3.None, data0); + } + + + GlobalConfiguration.Setup(new() { ConversionType = ConversionType.Default, EnumHandling = EnumHandling.ThrowError }); + using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb).EnsureOpen()) + { + // Act Query + var data = connection.ExecuteQuery("SELECT 'North' AS Value;").First(); + var data0 = connection.ExecuteQuery("SELECT 'None' AS Value;").First(); + var data3 = connection.ExecuteQuery("SELECT '3' AS Value;").First(); + try + { + var data10 = connection.ExecuteQuery("SELECT 'Center' AS Value;").First(); + Assert.Fail("Should have failed Direction/3"); + } + catch (ArgumentOutOfRangeException e) + { + Assert.IsTrue(e.Message.Contains(nameof(Direction4))); + + // We are in an EN-US scope so the message should match + Assert.AreEqual("Invalid value for Direction4 (Parameter 'value')\nActual value was Center.", e.Message.Replace("\r", "")); + } + + try + { + var data9 = connection.ExecuteQuery("SELECT '9' AS Value;").First(); + Assert.Fail("Should have failed Direction/9"); + } + catch (ArgumentOutOfRangeException e) + { + Assert.IsTrue(e.Message.Contains(nameof(Direction4))); + + // We are in an EN-US scope so the message should match + Assert.AreEqual("Invalid value for Direction4 (Parameter 'value')\nActual value was 9.", e.Message.Replace("\r", "")); + } + + // Assert + Assert.AreEqual(Direction4.North, data); + Assert.AreEqual(Direction4.South, data3); + Assert.AreEqual(Direction4.None, data0); + } + } + + [TestMethod] + public void TestSqlConnectionExecuteQueryConversionFromStringToEnumFlags() + { + using var _ = new CultureScope("EN-US"); + + // With automatic conversion + using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb).EnsureOpen()) + { + // Act Query + var data = connection.ExecuteQuery("SELECT 'North, East' AS Value;").First(); + var data2 = connection.ExecuteQuery("SELECT 'North, West' AS Value;").First(); + + // Assert + Assert.AreEqual(Direction.South, data); // Flag behavior + Assert.AreEqual(Direction.North | Direction.West, data2); // Flag behavior + } + + GlobalConfiguration.Setup(new() { ConversionType = ConversionType.Default, EnumHandling = EnumHandling.UseDefault }); + + // With default conversion + using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb).EnsureOpen()) + { + // Act Query + var data = connection.ExecuteQuery("SELECT 'North, East' AS Value;").First(); + var data2 = connection.ExecuteQuery("SELECT 'North, West' AS Value;").First(); + + // Assert + Assert.AreEqual(Direction2.South, data); // Flag behavior + Assert.AreEqual(Direction2.None, data2); // Not defined + } + + + GlobalConfiguration.Setup(new() { ConversionType = ConversionType.Default, EnumHandling = EnumHandling.ThrowError }); + + // With default conversion + using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb).EnsureOpen()) + { + // Act Query + var data = connection.ExecuteQuery("SELECT 'North, East' AS Value;").First(); + + try + { + var data2 = connection.ExecuteQuery("SELECT 'North, West' AS Value;").First(); + Assert.Fail("Should have failed Direction3/North, West"); + } + catch (ArgumentOutOfRangeException e) + { + Assert.IsTrue(e.Message.Contains(nameof(Direction3))); + + // We are in an EN-US scope so the message should match + Assert.AreEqual("Invalid value for Direction3 (Parameter 'value')\nActual value was North, West.", e.Message.Replace("\r", "")); + } + + Assert.AreEqual(Direction3.South, data); + } + } + #endregion #region Query @@ -521,6 +818,7 @@ private class StringToDecimalClass [TestMethod] public void TestSqlConnectionInsertAndQueryConversionFromStringToDecimal() { + using var _ = new CultureScope("EN-US"); // Setup var entity = new StringToDecimalClass { @@ -556,6 +854,7 @@ private class StringToFloatClass [TestMethod] public void TestSqlConnectionInsertAndQueryConversionFromStringToFloat() { + using var _ = new CultureScope("EN-US"); // Setup var entity = new StringToFloatClass { @@ -626,6 +925,7 @@ private class StringToMoneyClass [TestMethod] public void TestSqlConnectionInsertAndQueryConversionFromStringToMoney() { + using var _ = new CultureScope("EN-US"); // Setup var entity = new StringToMoneyClass { @@ -661,6 +961,7 @@ private class StringToNumericClass [TestMethod] public void TestSqlConnectionInsertAndQueryConversionFromStringToNumeric() { + using var _ = new CultureScope("EN-US"); // Setup var entity = new StringToNumericClass { @@ -696,6 +997,7 @@ private class StringToRealClass [TestMethod] public void TestSqlConnectionInsertAndQueryConversionFromStringToReal() { + using var _ = new CultureScope("EN-US"); // Setup var entity = new StringToRealClass { @@ -766,6 +1068,7 @@ private class StringToSmallMoneyClass [TestMethod] public void TestSqlConnectionInsertAndQueryConversionFromStringToSmallMoney() { + using var _ = new CultureScope("EN-US"); // Setup var entity = new StringToSmallMoneyClass { diff --git a/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/Equalities/QueryGroupEqualityTest.cs b/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/Equalities/QueryGroupEqualityTest.cs index 14d8f34ec..8409ca570 100644 --- a/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/Equalities/QueryGroupEqualityTest.cs +++ b/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/Equalities/QueryGroupEqualityTest.cs @@ -1,8 +1,8 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Collections; +using System.Collections.Generic; +using Microsoft.VisualStudio.TestTools.UnitTesting; using RepoDb.Enumerations; using RepoDb.Extensions; -using System.Collections; -using System.Collections.Generic; namespace RepoDb.UnitTests.Equalities { @@ -128,6 +128,22 @@ public void TestQueryGroupHashCodeEqualityForCollidedExpressions() // Assert Assert.IsFalse(equal); + Assert.AreEqual(objA.QueryGroups.Count, objB.QueryGroups.Count); + } + + [TestMethod] + public void TestQueryGroupHashCodeEqualityForCollidedExpressions2() + { + // Prepare + var objA = QueryGroup.Parse(c => c.Id == 1 && !(c.Value != 1)); + var objB = QueryGroup.Parse(c => c.Id != 1 && c.Value == 1); + + // Act + var equal = (objA.GetHashCode() == objB.GetHashCode()); + + // Assert + Assert.IsFalse(equal); + Assert.AreEqual(objA.QueryGroups?.Count, objB.QueryGroups?.Count); } [TestMethod] diff --git a/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/Mappers/MappingSequenceTest.cs b/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/Mappers/MappingSequenceTest.cs index b88ea4a78..746b7d2ed 100644 --- a/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/Mappers/MappingSequenceTest.cs +++ b/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/Mappers/MappingSequenceTest.cs @@ -1,13 +1,10 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using RepoDb.Interfaces; -using RepoDb.Attributes; -using RepoDb.UnitTests.CustomObjects; -using System; -using System.Linq; -using System.Collections.Generic; +using System; using System.Data; -using System.Text; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using RepoDb.Attributes; +using RepoDb.Interfaces; using RepoDb.Options; +using RepoDb.UnitTests.CustomObjects; namespace RepoDb.UnitTests.Mappers { diff --git a/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/RepoDb.UnitTests.csproj b/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/RepoDb.UnitTests.csproj index d3f47bf71..1013c1d15 100644 --- a/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/RepoDb.UnitTests.csproj +++ b/RepoDb.Core/RepoDb.Tests/RepoDb.UnitTests/RepoDb.UnitTests.csproj @@ -1,10 +1,11 @@  - net6.0;net7.0;net8.0 false + true + true + true - @@ -15,17 +16,13 @@ - - - - - - + + + - - + \ No newline at end of file diff --git a/RepoDb.Core/RepoDb/Compat.cs b/RepoDb.Core/RepoDb/Compat.cs new file mode 100644 index 000000000..0cab4c37f --- /dev/null +++ b/RepoDb.Core/RepoDb/Compat.cs @@ -0,0 +1,9 @@ +namespace System.Runtime.CompilerServices +{ +#if !NET + // Required to allow init properties in netstandard + internal sealed class IsExternalInit : Attribute + { + } +#endif +} diff --git a/RepoDb.Core/RepoDb/DbField.cs b/RepoDb.Core/RepoDb/DbField.cs index 0d2b8386d..d8dda9d7e 100644 --- a/RepoDb.Core/RepoDb/DbField.cs +++ b/RepoDb.Core/RepoDb/DbField.cs @@ -119,6 +119,13 @@ public DbField(string name, /// public string Provider { get; } + + /// + /// Gets the type to map to, including nullable + /// + /// + public Type TypeNullable() => IsNullable && Type.IsValueType ? typeof(System.Nullable<>).MakeGenericType(Type) : Type; + #endregion #region Methods diff --git a/RepoDb.Core/RepoDb/Enumerations/EnumHandling.cs b/RepoDb.Core/RepoDb/Enumerations/EnumHandling.cs new file mode 100644 index 000000000..3f4a49b45 --- /dev/null +++ b/RepoDb.Core/RepoDb/Enumerations/EnumHandling.cs @@ -0,0 +1,21 @@ +namespace RepoDb.Enumerations +{ + /// + /// + /// + public enum EnumHandling + { + /// + /// Throw an error when encountering non defined enum values. For enums decorated with a no value check is performed. + /// + ThrowError = 0, + /// + /// Use the default (0) value of the enum when encountering non defined enum values, For enums decorated with a no value check is performed. + /// + UseDefault = 1, + /// + /// Assumes all matched strings and integer values are valid. + /// + Cast = 2 + } +} diff --git a/RepoDb.Core/RepoDb/Mappers/DbSettingMapper.cs b/RepoDb.Core/RepoDb/Mappers/DbSettingMapper.cs index 88e9a88c1..cdab33a77 100644 --- a/RepoDb.Core/RepoDb/Mappers/DbSettingMapper.cs +++ b/RepoDb.Core/RepoDb/Mappers/DbSettingMapper.cs @@ -1,8 +1,8 @@ -using RepoDb.Exceptions; -using RepoDb.Interfaces; -using System; +using System; using System.Collections.Concurrent; using System.Data; +using RepoDb.Exceptions; +using RepoDb.Interfaces; namespace RepoDb { @@ -77,7 +77,7 @@ public static IDbSetting Get() /// /// The type of . /// The instance of . - /// The instance of exising mapped object. + /// The instance of existing mapped object. public static IDbSetting Get(TDbConnection connection) where TDbConnection : IDbConnection { diff --git a/RepoDb.Core/RepoDb/Options/GlobalConfigurationOptions.cs b/RepoDb.Core/RepoDb/Options/GlobalConfigurationOptions.cs index faef5fac3..8214e9cdb 100644 --- a/RepoDb.Core/RepoDb/Options/GlobalConfigurationOptions.cs +++ b/RepoDb.Core/RepoDb/Options/GlobalConfigurationOptions.cs @@ -1,37 +1,42 @@ -using RepoDb.Enumerations; -using System.Data; +using System.Data; using System.Data.Common; +using RepoDb.Enumerations; namespace RepoDb.Options { /// /// A class that is being used to define the globalized configurations for the application. /// - public class GlobalConfigurationOptions + public record GlobalConfigurationOptions { /// /// Gets or sets the value that defines the conversion logic when converting an instance of into a .NET CLR class. /// - public ConversionType ConversionType { get; set; } = ConversionType.Default; + public ConversionType ConversionType { get; init; } = ConversionType.Default; + + /// + /// Gets or sets the handling of invalid enum values when converting an instance of into .NET enum values + /// + public EnumHandling EnumHandling { get; init; } = EnumHandling.ThrowError; /// /// Gets or sets the default value of the batch operation size. The value defines on this property mainly affects the batch size of the InsertAll, MergeAll and UpdateAll operations. /// - public int DefaultBatchOperationSize { get; set; } = Constant.DefaultBatchOperationSize; + public int DefaultBatchOperationSize { get; init; } = Constant.DefaultBatchOperationSize; /// /// Gets of sets the default value of the cache expiration in minutes. /// - public int DefaultCacheItemExpirationInMinutes { get; set; } = Constant.DefaultCacheItemExpirationInMinutes; + public int DefaultCacheItemExpirationInMinutes { get; init; } = Constant.DefaultCacheItemExpirationInMinutes; /// /// Gets or sets the default equivalent of an enumeration if it is being used as a parameter to the execution of any non-entity-based operations. /// - public DbType EnumDefaultDatabaseType { get; set; } = DbType.String; + public DbType EnumDefaultDatabaseType { get; init; } = DbType.String; /// /// Gets or sets the default value of how the push operations (i.e.: Insert, InsertAll, Merge and MergeAll) behaves when returning the value from the key columns (i.e.: Primary and Identity). /// - public KeyColumnReturnBehavior KeyColumnReturnBehavior { get; set; } = KeyColumnReturnBehavior.IdentityOrElsePrimary; + public KeyColumnReturnBehavior KeyColumnReturnBehavior { get; init; } = KeyColumnReturnBehavior.IdentityOrElsePrimary; } } diff --git a/RepoDb.Core/RepoDb/QueryGroup/ParseExpression.cs b/RepoDb.Core/RepoDb/QueryGroup/ParseExpression.cs index 26b13d28c..1e5f88bc7 100644 --- a/RepoDb.Core/RepoDb/QueryGroup/ParseExpression.cs +++ b/RepoDb.Core/RepoDb/QueryGroup/ParseExpression.cs @@ -1,8 +1,8 @@ -using RepoDb.Enumerations; -using RepoDb.Extensions; -using System; +using System; using System.Linq; using System.Linq.Expressions; +using RepoDb.Enumerations; +using RepoDb.Extensions; namespace RepoDb { @@ -145,12 +145,29 @@ private static QueryGroup Parse(BinaryExpression expression) private static QueryGroup Parse(UnaryExpression expression) where TEntity : class { - return expression.Operand switch + if (expression.NodeType == ExpressionType.Not || expression.NodeType == ExpressionType.Convert) { - MemberExpression memberExpression => Parse(memberExpression, expression.NodeType), - MethodCallExpression methodCallExpression => Parse(methodCallExpression, expression.NodeType), - _ => null - }; + // These two handle + if (expression.Operand is MemberExpression memberExpression && Parse(memberExpression, expression.NodeType) is { } r1) + return r1; + else if (expression.Operand is MethodCallExpression methodCallExpression && Parse(methodCallExpression, expression.NodeType) is { } r2) + return r2; + } + + if (Parse(expression.Operand) is { } r) + { + if (expression.NodeType == ExpressionType.Not) + { + // Wrap result in A NOT expression + return new QueryGroup(r, true); + } + else + return new QueryGroup(r, false); + } + else + { + throw new NotSupportedException($"Unary operation '{expression.NodeType}' is currently not supported."); + } } /* diff --git a/RepoDb.Core/RepoDb/Reflection/Compiler/Options.cs b/RepoDb.Core/RepoDb/Reflection/Compiler/Compiler.Options.cs similarity index 100% rename from RepoDb.Core/RepoDb/Reflection/Compiler/Options.cs rename to RepoDb.Core/RepoDb/Reflection/Compiler/Compiler.Options.cs diff --git a/RepoDb.Core/RepoDb/Reflection/Compiler/Compiler.cs b/RepoDb.Core/RepoDb/Reflection/Compiler/Compiler.cs index d62f2a4ab..9731a7e84 100644 --- a/RepoDb.Core/RepoDb/Reflection/Compiler/Compiler.cs +++ b/RepoDb.Core/RepoDb/Reflection/Compiler/Compiler.cs @@ -1,15 +1,16 @@ -using RepoDb.Enumerations; -using RepoDb.Exceptions; -using RepoDb.Extensions; -using RepoDb.Interfaces; -using RepoDb.Resolvers; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Data; using System.Data.Common; using System.Linq; using System.Linq.Expressions; using System.Reflection; +using RepoDb.Enumerations; +using RepoDb.Exceptions; +using RepoDb.Extensions; +using RepoDb.Interfaces; +using RepoDb.Resolvers; namespace RepoDb.Reflection { @@ -519,13 +520,6 @@ internal static MethodInfo GetDateTimeFromDateOnlyMethod() => StaticType.DateOnly.GetMethod("ToDateTime", new Type[] { StaticType.TimeOnly }); #endif - /// - /// - /// - /// - internal static MethodInfo GetEnumParseMethod() => - StaticType.Enum.GetMethod("Parse", new[] { StaticType.Type, StaticType.String, StaticType.Boolean }); - /// /// /// @@ -540,18 +534,40 @@ internal static MethodInfo GetEnumGetNameMethod() => internal static MethodInfo GetEnumIsDefinedMethod() => StaticType.Enum.GetMethod("IsDefined", new[] { StaticType.Type, StaticType.Object }); + + internal static MethodInfo GetEnumParseNullMethod() => + typeof(Compiler).GetMethod(nameof(EnumParseNull), BindingFlags.Static | BindingFlags.NonPublic); + + private static TEnum? EnumParseNull(string value) where TEnum : struct, System.Enum + { + if (Enum.TryParse(value, true, out var r)) + return r; + else + return null; + } + + internal static MethodInfo GetEnumParseNullDefinedMethod() => + typeof(Compiler).GetMethod(nameof(EnumParseNullDefined), BindingFlags.Static | BindingFlags.NonPublic); + + private static TEnum? EnumParseNullDefined(string value) where TEnum : struct, System.Enum + { + if (Enum.TryParse(value, true, out var r) && Enum.IsDefined(typeof(TEnum), r)) + return r; + else + return null; + } + /// /// /// /// + /// /// - internal static Expression ConvertExpressionToNullableGetValueOrDefaultExpression(Expression expression) + internal static Expression ConvertExpressionToNullableValue(Expression expression) { - if (Nullable.GetUnderlyingType(expression.Type) != null) + if (Nullable.GetUnderlyingType(expression.Type) is { } underlyingType) { - var underlyingType = TypeCache.Get(expression.Type).GetUnderlyingType(); - var method = expression.Type.GetMethod("GetValueOrDefault", new Type[] { underlyingType }); - return Expression.Call(expression, method, Expression.Default(underlyingType)); + return Expression.Property(expression, nameof(Nullable.Value)); } return expression; } @@ -561,7 +577,7 @@ internal static Expression ConvertExpressionToNullableGetValueOrDefaultExpressio { if (Nullable.GetUnderlyingType(expression.Type) != null) { - var converted = converter(ConvertExpressionToNullableGetValueOrDefaultExpression(expression)); + var converted = converter(ConvertExpressionToNullableValue(expression)); var nullableType = typeof(Nullable<>).MakeGenericType(converted.Type); return Expression.Condition( Expression.Property(expression, nameof(Nullable.HasValue)), @@ -594,7 +610,7 @@ internal static Expression ConvertExpressionToNullableValueExpression(Expression /// /// internal static Expression ConvertExpressionToGuidToStringExpression(Expression expression) => - Expression.Call(ConvertExpressionToNullableGetValueOrDefaultExpression(expression), StaticType.Guid.GetMethod("ToString", Array.Empty())); + Expression.Call(ConvertExpressionToNullableValue(expression), StaticType.Guid.GetMethod("ToString", Array.Empty())); /// /// @@ -602,7 +618,7 @@ internal static Expression ConvertExpressionToGuidToStringExpression(Expression /// /// internal static Expression ConvertExpressionToStringToGuidExpression(Expression expression) => - Expression.New(StaticType.Guid.GetConstructor(new[] { StaticType.String }), ConvertExpressionToNullableGetValueOrDefaultExpression(expression)); + Expression.New(StaticType.Guid.GetConstructor(new[] { StaticType.String }), ConvertExpressionToNullableValue(expression)); /// /// @@ -611,7 +627,7 @@ internal static Expression ConvertExpressionToStringToGuidExpression(Expression /// internal static Expression ConvertExpressionToTimeSpanToDateTimeExpression(Expression expression) => Expression.New(StaticType.DateTime.GetConstructor(new[] { StaticType.Int64 }), - ConvertExpressionToNullableGetValueOrDefaultExpression(ConvertExpressionToTimeSpanTicksExpression(expression))); + ConvertExpressionToNullableValue(ConvertExpressionToTimeSpanTicksExpression(expression))); /// /// @@ -619,7 +635,7 @@ internal static Expression ConvertExpressionToTimeSpanToDateTimeExpression(Expre /// /// internal static Expression ConvertExpressionToDateTimeToTimeSpanExpression(Expression expression) => - ConvertExpressionToNullableGetValueOrDefaultExpression(ConvertExpressionToDateTimeTimeOfDayExpression(expression)); + ConvertExpressionToNullableValue(ConvertExpressionToDateTimeTimeOfDayExpression(expression)); #if NET6_0_OR_GREATER /// /// @@ -678,38 +694,89 @@ internal static Expression ConvertExpressionToDateTimeFromDateOnlyExpression(Exp internal static Expression ConvertExpressionToSystemConvertExpression(Expression expression, Type toType) { - if (TypeCache.Get(expression.Type).GetUnderlyingType() == toType) + var fromType = expression.Type; + var underlyingFromType = TypeCache.Get(fromType).GetUnderlyingType(); + var underlyingToType = TypeCache.Get(toType).GetUnderlyingType(); + + if (fromType == toType) { return expression; } // Identify - if (toType.IsAssignableFrom(expression.Type)) + if (underlyingToType.IsAssignableFrom(fromType)) { - return ConvertExpressionToTypeExpression(expression, toType); + return ConvertExpressionToTypeExpression(expression, underlyingToType); } + var result = ConvertExpressionToNullableValue(expression); + // Convert.To() - var methodInfo = GetSystemConvertToTypeMethod(expression.Type, toType); - if (methodInfo != null) + if (underlyingFromType.IsEnum) { - return Expression.Call(methodInfo, ConvertExpressionToNullableGetValueOrDefaultExpression(expression)); - } + if (underlyingToType == StaticType.String) + { + result = Expression.Call(result, nameof(ToString), Array.Empty()); + } + else if (underlyingToType.IsPrimitive && + (underlyingToType) == StaticType.Int16 + || underlyingToType == StaticType.Int32 + || underlyingToType == StaticType.Int64 + || underlyingToType == StaticType.Byte + || underlyingToType == StaticType.UInt16 + || underlyingToType == StaticType.UInt32 + || underlyingToType == StaticType.UInt64 + || underlyingToType == StaticType.SByte) + { + result = Expression.Convert(result, Enum.GetUnderlyingType(underlyingFromType)); - // Convert.ChangeType - methodInfo = GetSystemConvertChangeTypeMethod(toType); - if (methodInfo != null) + if (result.Type != underlyingToType) + result = Expression.Convert(result, underlyingToType); + } + else + return result; // Will fail + } + else if (GetSystemConvertToTypeMethod(underlyingFromType, underlyingToType) is { } methodInfo) { - expression = ConvertExpressionToNullableGetValueOrDefaultExpression(expression); - return Expression.Call(methodInfo, new Expression[] + result = Expression.Call(methodInfo, result); + } + else if (GetSystemConvertChangeTypeMethod(underlyingToType) is { } systemChangeType) + { + result = Expression.Call(systemChangeType, new Expression[] { - ConvertExpressionToTypeExpression(expression, StaticType.Object), - Expression.Constant(TypeCache.Get(toType).GetUnderlyingType()) + ConvertExpressionToTypeExpression(result, StaticType.Object), + Expression.Constant(TypeCache.Get(underlyingToType).GetUnderlyingType()) }); } + else + { + return result; // Will fail! + } + + // Do we need manual NULL handling? + if ((!underlyingToType.IsValueType || underlyingToType != toType) + && (!underlyingFromType.IsValueType || underlyingFromType != fromType)) + { + Expression condition; + if (underlyingFromType != fromType) + { + // E.g. Nullable -> string + condition = Expression.Property(expression, nameof(Nullable.HasValue)); + } + else + { + // E.g. String -> Nullable + condition = Expression.NotEqual(expression, Expression.Constant(null, expression.Type)); + } + + return Expression.Condition( + condition, + (result.Type != toType) ? Expression.Convert(result, toType) : result, + Expression.Constant(null, toType)); + } // Return - return expression; + return result; } /// @@ -745,17 +812,21 @@ internal static Expression ConvertExpressionToEnumExpression(Expression expressi internal static Expression ConvertExpressionToEnumExpressionForString(Expression expression, Type toEnumType) { - var trueExpression = GetEnumParseExpression(expression, toEnumType, true); - if (GlobalConfiguration.Options.ConversionType == ConversionType.Automatic) - { - var isDefinedExpression = GetEnumIsDefinedExpression(expression, toEnumType); - var falseExpression = ConvertExpressionToTypeExpression(Expression.Default(toEnumType), StaticType.Object); - return Expression.Condition(isDefinedExpression, trueExpression, falseExpression); - } - else - { - return trueExpression; - } + var checkMethod = (GlobalConfiguration.Options.ConversionType == ConversionType.Automatic || GlobalConfiguration.Options.EnumHandling == EnumHandling.Cast || toEnumType.GetCustomAttribute() != null) + ? GetEnumParseNullMethod() + : GetEnumParseNullDefinedMethod(); + + return Expression.Coalesce( + Expression.Call(checkMethod.MakeGenericMethod(toEnumType), expression), + + (GlobalConfiguration.Options.EnumHandling == EnumHandling.UseDefault) + ? Expression.Default(toEnumType) + : Expression.Throw(Expression.New( + typeof(ArgumentOutOfRangeException).GetConstructor(new[] { StaticType.String, StaticType.Object, StaticType.String }), + Expression.Constant("value"), + expression, + Expression.Constant($"Invalid value for {toEnumType.Name}")), + toEnumType)); } /// @@ -767,14 +838,28 @@ internal static Expression ConvertExpressionToEnumExpressionForString(Expression internal static Expression ConvertExpressionToEnumExpressionForNonString(Expression expression, Type toEnumType) { - if (GlobalConfiguration.Options.ConversionType == ConversionType.Automatic) + if (GlobalConfiguration.Options.ConversionType == ConversionType.Automatic || GlobalConfiguration.Options.EnumHandling == EnumHandling.Cast) { return Expression.Convert(expression, toEnumType); } else { - return ConvertExpressionToEnumExpressionForString( - GetEnumGetNameExpression(expression, toEnumType), toEnumType); + // Handle long/short to enum and/or non integer based enums + if (expression.Type != Enum.GetUnderlyingType(toEnumType)) + expression = Expression.Convert(expression, Enum.GetUnderlyingType(toEnumType)); + + return Expression.Condition( + GetEnumIsDefinedExpression(expression, toEnumType), // Check if the value is defined + Expression.Convert(expression, toEnumType), // Cast to enum + GlobalConfiguration.Options.EnumHandling switch + { + EnumHandling.UseDefault => Expression.Default(toEnumType), + EnumHandling.ThrowError => Expression.Throw(Expression.New(typeof(InvalidEnumArgumentException).GetConstructor(new[] { StaticType.String, StaticType.Int32, StaticType.Type }), + new Expression[] { Expression.Constant("value"), Expression.Convert(expression, StaticType.Int32), Expression.Constant(toEnumType) }), + toEnumType + ), + _ => throw new InvalidEnumArgumentException("EnumHandling set to invalid value") + }); // Default value for undefined } } @@ -913,12 +998,13 @@ internal static Expression ConvertExpressionToNullableExpression(Expression expr /// /// /// - /// + /// /// internal static Expression ConvertExpressionWithAutomaticConversion(Expression expression, - Type toType) + Type trueToType) { var fromType = TypeCache.Get(expression.Type).GetUnderlyingType(); + var toType = TypeCache.Get(trueToType)?.GetUnderlyingType(); // Guid to String if (fromType == StaticType.Guid && toType == StaticType.String) @@ -959,7 +1045,7 @@ internal static Expression ConvertExpressionWithAutomaticConversion(Expression e // Others else { - expression = ConvertExpressionToSystemConvertExpression(expression, toType); + expression = ConvertExpressionToSystemConvertExpression(expression, trueToType); } // Return @@ -1136,26 +1222,6 @@ internal static Expression ConvertExpressionToClassHandlerSetExpression(Expressi #region Common - /// - /// - /// - /// - /// - /// - /// - internal static Expression GetEnumParseExpression(Expression expression, - Type enumType, - bool ignoreCase) - { - var parameters = new Expression[] - { - Expression.Constant(enumType), - expression, - Expression.Constant(ignoreCase) - }; - return Expression.Call(GetEnumParseMethod(), parameters); - } - /// /// /// @@ -1332,7 +1398,7 @@ internal static Expression GetClassPropertyParameterInfoIsDbNullFalseValueExpres { try { - valueExpression = ConvertExpressionWithAutomaticConversion(valueExpression, targetTypeUnderlyingType); + valueExpression = ConvertExpressionWithAutomaticConversion(valueExpression, targetType); } catch (Exception ex) { @@ -1611,7 +1677,7 @@ internal static Expression GetEntityInstancePropertyValueExpression(Expression e // Target type var handlerInstance = classProperty.GetPropertyHandler() ?? PropertyHandlerCache.Get(TypeCache.Get(dbField.Type).GetUnderlyingType()); - var targetType = GetPropertyHandlerSetParameter(handlerInstance)?.ParameterType ?? dbField.Type; + var targetType = GetPropertyHandlerSetParameter(handlerInstance)?.ParameterType ?? dbField.TypeNullable(); /* * Note: The other data provider can coerce the Enum into its destination data type in the DB by default, @@ -1625,8 +1691,10 @@ internal static Expression GetEntityInstancePropertyValueExpression(Expression e { if (!IsPostgreSqlUserDefined(dbField)) { - var dbType = classProperty.GetDbType() ?? TypeCache.Get(classProperty.PropertyInfo.PropertyType).GetUnderlyingType().GetDbType(); - var toType = dbType.HasValue ? new DbTypeToClientTypeResolver().Resolve(dbType.Value) : TypeCache.Get(targetType)?.GetUnderlyingType(); + var enumType = TypeCache.Get(classProperty.PropertyInfo.PropertyType).GetUnderlyingType(); + var dbType = classProperty.GetDbType() ?? enumType.GetDbType(); + var toType = dbType.HasValue ? new DbTypeToClientTypeResolver().Resolve(dbType.Value) : targetType; + expression = ConvertEnumExpressionToTypeExpression(expression, toType); } } @@ -1642,7 +1710,21 @@ internal static Expression GetEntityInstancePropertyValueExpression(Expression e { try { - expression = ConvertExpressionWithAutomaticConversion(expression, TypeCache.Get(targetType)?.GetUnderlyingType()); + var origExpression = expression; + expression = ConvertExpressionWithAutomaticConversion(expression, targetType); + + if (dbField?.IsIdentity == true + && targetType.IsValueType && TypeCache.Get(targetType).GetUnderlyingType() == targetType + && TypeCache.Get(origExpression.Type).GetUnderlyingType() != origExpression.Type) + { + var nullableType = typeof(Nullable<>).MakeGenericType(expression.Type); + + // Don't set '0' in the identity output property + expression = Expression.Condition( + Expression.Property(origExpression, nameof(Nullable.HasValue)), + Expression.Convert(expression, nullableType), + Expression.Constant(null, nullableType)); + } } catch (Exception ex) { diff --git a/RepoDb.Core/RepoDb/Reflection/Compiler/PlainTypeToDbParameters.cs b/RepoDb.Core/RepoDb/Reflection/Compiler/PlainTypeToDbParameters.cs index 3513fd006..6c5ac7e9d 100644 --- a/RepoDb.Core/RepoDb/Reflection/Compiler/PlainTypeToDbParameters.cs +++ b/RepoDb.Core/RepoDb/Reflection/Compiler/PlainTypeToDbParameters.cs @@ -1,12 +1,12 @@ -using RepoDb.Enumerations; -using RepoDb.Extensions; -using RepoDb.Resolvers; -using System; +using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq; using System.Linq.Expressions; +using RepoDb.Enumerations; +using RepoDb.Extensions; +using RepoDb.Resolvers; namespace RepoDb.Reflection { @@ -33,7 +33,7 @@ internal static Action GetPlainTypeToDbParametersCompiledFunc foreach (var paramProperty in PropertyCache.Get(paramType)) { var mappedParamPropertyName = paramProperty.GetMappedName(); - + // Ensure it matches to atleast one param var entityProperty = PropertyCache.Get(entityType)?.FirstOrDefault(e => string.Equals(e.GetMappedName(), mappedParamPropertyName, StringComparison.OrdinalIgnoreCase) || @@ -66,7 +66,8 @@ internal static Action GetPlainTypeToDbParametersCompiledFunc { #region NewParameter - var underlyingType = TypeCache.Get(targetProperty.PropertyInfo.PropertyType).GetUnderlyingType(); + var propertyType = targetProperty.PropertyInfo.PropertyType; + var underlyingType = TypeCache.Get(propertyType).GetUnderlyingType(); var valueType = GetPropertyHandlerSetMethodReturnType(paramProperty, underlyingType) ?? underlyingType; var dbParameterExpression = Expression.Variable(StaticType.DbParameter, $"var{parameterName}"); var parameterCallExpressions = new List(); @@ -79,11 +80,6 @@ internal static Action GetPlainTypeToDbParametersCompiledFunc ConvertExpressionToTypeExpression(createParameterExpression, StaticType.DbParameter))); // Convert - if (GlobalConfiguration.Options.ConversionType == ConversionType.Automatic && dbField?.Type != null) - { - valueType = TypeCache.Get(dbField.Type).GetUnderlyingType(); - valueExpression = ConvertExpressionWithAutomaticConversion(valueExpression, valueType); - } // DbType var dbType = (DbType?)null; @@ -100,18 +96,17 @@ internal static Action GetPlainTypeToDbParametersCompiledFunc valueType.GetDbType() ?? (dbField != null ? new ClientTypeToDbTypeResolver().Resolve(dbField.Type) : null) ?? (DbType?)GlobalConfiguration.Options.EnumDefaultDatabaseType; - - if (GlobalConfiguration.Options.ConversionType == ConversionType.Automatic) - { - var toType = dbType.HasValue ? new DbTypeToClientTypeResolver().Resolve(dbType.Value) : TypeCache.Get(valueType)?.GetUnderlyingType(); - valueExpression = ConvertEnumExpressionToTypeExpression(valueExpression, toType); - } - } + } else { dbType = default; } } + else if (GlobalConfiguration.Options.ConversionType == ConversionType.Automatic && dbField?.Type != null) + { + valueExpression = ConvertExpressionWithAutomaticConversion(valueExpression, dbField.TypeNullable()); + dbType = default; + } else { var targetType = TypeCache.Get(dbField?.Type).GetUnderlyingType() ?? valueType; diff --git a/RepoDb.Core/RepoDb/RepoDb.csproj b/RepoDb.Core/RepoDb/RepoDb.csproj index 73ba09b1b..c3c702b34 100644 --- a/RepoDb.Core/RepoDb/RepoDb.csproj +++ b/RepoDb.Core/RepoDb/RepoDb.csproj @@ -1,60 +1,45 @@  - - - RepoDB - netstandard2.0;net6.0;net7.0;net8.0 - 0.0.1 - 0.0.1 - 0.0.1 - A hybrid ORM library for .NET. - orm hybrid-orm micro-orm - http://repodb.net/release/core - https://repodb.net/ - https://github.com/mikependon/RepoDb/tree/master/RepoDb.Core - True - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - - - - - - - - <_Parameter1>RepoDb.UnitTests - - - - - - - - \ No newline at end of file + + RepoDB + netstandard2.0;net6.0;net7.0;net8.0 + annotations + A hybrid ORM library for .NET. + orm hybrid-orm micro-orm + http://repodb.net/release/core + https://repodb.net/ + https://github.com/mikependon/RepoDb/tree/master/RepoDb.Core + + + + $(NoWarn);CS8604 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RepoDb.Core/RepoDb/StaticType.cs b/RepoDb.Core/RepoDb/StaticType.cs index c762dc3d9..cf0e27402 100644 --- a/RepoDb.Core/RepoDb/StaticType.cs +++ b/RepoDb.Core/RepoDb/StaticType.cs @@ -1,17 +1,17 @@ -using RepoDb.Attributes; -using RepoDb.Attributes.Parameter; -using RepoDb.Enumerations; -using RepoDb.Extensions; -using RepoDb.Interfaces; -using RepoDb.Options; -using RepoDb.Types; -using System; +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using System.Data; using System.Data.Common; using System.Dynamic; using System.Reflection; +using RepoDb.Attributes; +using RepoDb.Attributes.Parameter; +using RepoDb.Enumerations; +using RepoDb.Extensions; +using RepoDb.Interfaces; +using RepoDb.Options; +using RepoDb.Types; namespace RepoDb { @@ -95,8 +95,8 @@ internal static class StaticType /// Gets a type of the .NET CLR type. /// public static Type DateTimeOffset => typeof(DateTimeOffset); - - #if NET6_0_OR_GREATER + +#if NET6_0_OR_GREATER /// /// Gets a type of the .NET CLR type. /// @@ -105,8 +105,8 @@ internal static class StaticType /// Gets a type of the .NET CLR type. /// public static Type TimeOnly => typeof(TimeOnly); - #endif - +#endif + /// /// Gets a type of the .NET CLR type. /// @@ -376,5 +376,10 @@ internal static class StaticType /// Gets a type of the .NET CLR type. /// public static Type UInt64 => typeof(ulong); + + /// + /// Gets a type of the .NET CLR type. + /// + public static Type SByte => typeof(sbyte); } } diff --git a/RepoDb.Core/RepoDb/Trace/CancellableTraceLog.cs b/RepoDb.Core/RepoDb/Trace/CancellableTraceLog.cs index 5670adf0d..146ae9bc5 100644 --- a/RepoDb.Core/RepoDb/Trace/CancellableTraceLog.cs +++ b/RepoDb.Core/RepoDb/Trace/CancellableTraceLog.cs @@ -74,11 +74,11 @@ public void Cancel(bool throwException = true) /// /// The string representation of the current object. public override string ToString() => - $"SessiontId: {SessionId}\n" + + $"SessionId: {SessionId}\n" + $"Key: {Key}\n" + $"Statement: {Statement}\n" + - $"StarTime (Ticks): {StartTime.Ticks}\n" + - $"Parameters: {(Parameters?.Any() == true ? string.Join(", ", Parameters.ToArray().Select(param => $"({param.ParameterName}={param.Value})")) : "No Parameters")}"; + $"StartTime (Ticks): {StartTime.Ticks}\n" + + $"Parameters: {(Parameters?.Any() == true ? string.Join(", ", Parameters.ToArray().Select(param => $"({param.ParameterName}={(param.Value is DBNull ? "DBNull" : param.Value)})")) : "No Parameters")}"; #endregion } diff --git a/RepoDb.Extensions/RepoDb.PostgreSql.BulkOperations/RepoDb.PostgreSql.BulkOperations.IntegrationTests/RepoDb.PostgreSql.BulkOperations.IntegrationTests.csproj b/RepoDb.Extensions/RepoDb.PostgreSql.BulkOperations/RepoDb.PostgreSql.BulkOperations.IntegrationTests/RepoDb.PostgreSql.BulkOperations.IntegrationTests.csproj index f34dd3ade..739198bb4 100644 --- a/RepoDb.Extensions/RepoDb.PostgreSql.BulkOperations/RepoDb.PostgreSql.BulkOperations.IntegrationTests/RepoDb.PostgreSql.BulkOperations.IntegrationTests.csproj +++ b/RepoDb.Extensions/RepoDb.PostgreSql.BulkOperations/RepoDb.PostgreSql.BulkOperations.IntegrationTests/RepoDb.PostgreSql.BulkOperations.IntegrationTests.csproj @@ -1,28 +1,24 @@  - net6.0;net7.0;net8.0 false + true + true + true - - - - - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - diff --git a/RepoDb.Extensions/RepoDb.PostgreSql.BulkOperations/RepoDb.PostgreSql.BulkOperations.IntegrationTests/Setup/Database.cs b/RepoDb.Extensions/RepoDb.PostgreSql.BulkOperations/RepoDb.PostgreSql.BulkOperations.IntegrationTests/Setup/Database.cs index 3fd17a1c4..ee29fe7b5 100644 --- a/RepoDb.Extensions/RepoDb.PostgreSql.BulkOperations/RepoDb.PostgreSql.BulkOperations.IntegrationTests/Setup/Database.cs +++ b/RepoDb.Extensions/RepoDb.PostgreSql.BulkOperations/RepoDb.PostgreSql.BulkOperations.IntegrationTests/Setup/Database.cs @@ -1,5 +1,5 @@ -using Npgsql; -using System; +using System; +using Npgsql; namespace RepoDb.IntegrationTests.Setup { @@ -13,12 +13,20 @@ public static class Database /// public static void Initialize() { - // Set the connection string - ConnectionStringForPosgres = Environment.GetEnvironmentVariable("REPODB_CONSTR_POSTGRESDB", EnvironmentVariableTarget.Process) ?? - "Server=127.0.0.1;Port=5432;Database=postgres;User Id=postgres;Password=Password123;"; - ConnectionStringForRepoDb = Environment.GetEnvironmentVariable("REPODB_CONSTR", EnvironmentVariableTarget.Process)?? - "Server=127.0.0.1;Port=5432;Database=RepoDb;User Id=postgres;Password=Password123;"; - + // Master connection + ConnectionStringForPostgres = + Environment.GetEnvironmentVariable("REPODB_POSTGRESQL_CONSTR_POSTGRESDB") + ?? Environment.GetEnvironmentVariable("REPODB_CONSTR_POSTGRESDB") + //?? "Server=127.0.0.1;Port=45432;Database=postgres;User Id=postgres;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" // Docker test configuration + ?? "Server=127.0.0.1;Port=5432;Database=postgres;User Id=postgres;Password=Password123;"; + + // RepoDb connection + ConnectionStringForRepoDb = + Environment.GetEnvironmentVariable("REPODB_POSTGRESQL_CONSTR_BULK") + ?? Environment.GetEnvironmentVariable("REPODB_CONSTR_BULK") + //?? "Server=127.0.0.1;Port=45432;Database=RepoDbBulk;User Id=postgres;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" // Docker test configuration + ?? "Server=127.0.0.1;Port=5432;Database=RepoDbBulk;User Id=postgres;Password=Password123;"; + // Initialize PostgreSql GlobalConfiguration.Setup().UsePostgreSql(); @@ -32,7 +40,7 @@ public static void Initialize() /// /// Gets or sets the connection string to be used for Postgres database. /// - public static string ConnectionStringForPosgres { get; private set; } + public static string ConnectionStringForPostgres { get; private set; } /// /// Gets or sets the connection string to be used. @@ -46,12 +54,12 @@ public static void Initialize() /// public static void CreateDatabase() { - using (var connection = new NpgsqlConnection(ConnectionStringForPosgres)) + using (var connection = new NpgsqlConnection(ConnectionStringForPostgres)) { - var recordCount = connection.ExecuteScalar("SELECT COUNT(*) FROM pg_database WHERE datname = 'RepoDb';"); + var recordCount = connection.ExecuteScalar("SELECT COUNT(*) FROM pg_database WHERE datname = 'RepoDbBulk';"); if (recordCount <= 0) { - connection.ExecuteNonQuery(@"CREATE DATABASE ""RepoDb"" + connection.ExecuteNonQuery(@"CREATE DATABASE ""RepoDbBulk"" WITH OWNER = ""postgres"" ENCODING = ""UTF8"" CONNECTION LIMIT = -1;"); diff --git a/RepoDb.Extensions/RepoDb.PostgreSql.BulkOperations/RepoDb.PostgreSql.BulkOperations/RepoDb.PostgreSql.BulkOperations.csproj b/RepoDb.Extensions/RepoDb.PostgreSql.BulkOperations/RepoDb.PostgreSql.BulkOperations/RepoDb.PostgreSql.BulkOperations.csproj index 5050e1ebf..23f304422 100644 --- a/RepoDb.Extensions/RepoDb.PostgreSql.BulkOperations/RepoDb.PostgreSql.BulkOperations/RepoDb.PostgreSql.BulkOperations.csproj +++ b/RepoDb.Extensions/RepoDb.PostgreSql.BulkOperations/RepoDb.PostgreSql.BulkOperations/RepoDb.PostgreSql.BulkOperations.csproj @@ -1,39 +1,20 @@  - - - RepoDb.PostgreSql.BulkOperations - netstandard2.0;net6.0;net7.0;net8.0 - 0.0.1 - 0.0.1 - 0.0.1 - An extension library that contains the official Bulk Operations of RepoDb for PostgreSQL. - orm hybrid-orm micro-orm postgresql bulkoperations - https://github.com/mikependon/RepoDb/tree/master/RepoDb.Extensions/RepoDb.PostgreSql.BulkOperations - http://repodb.net/release/postgresqlbulk - true - true - https://repodb.net/tutorial/get-started-postgresql - - - - - - - - - - True - - - - - - - - - - - - - + + RepoDb.PostgreSql.BulkOperations + netstandard2.0;net6.0;net7.0;net8.0 + annotations + An extension library that contains the official Bulk Operations of RepoDb for PostgreSQL. + orm hybrid-orm micro-orm postgresql bulkoperations + https://github.com/mikependon/RepoDb/tree/master/RepoDb.Extensions/RepoDb.PostgreSql.BulkOperations + http://repodb.net/release/postgresqlbulk + https://repodb.net/tutorial/get-started-postgresql + + + + + + + + + diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations.IntegrationTests/RepoDb.SqlServer.BulkOperations.IntegrationTests.csproj b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations.IntegrationTests/RepoDb.SqlServer.BulkOperations.IntegrationTests.csproj index 780812c0d..7f376eda0 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations.IntegrationTests/RepoDb.SqlServer.BulkOperations.IntegrationTests.csproj +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations.IntegrationTests/RepoDb.SqlServer.BulkOperations.IntegrationTests.csproj @@ -1,10 +1,11 @@  - - net6.0;net7.0;net8.0 + net6.0;net7.0;net8.0 false + true + true + true - @@ -19,21 +20,16 @@ - - - - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + \ No newline at end of file diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations.IntegrationTests/Setup/Database.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations.IntegrationTests/Setup/Database.cs index 44f9d7eda..082dc7159 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations.IntegrationTests/Setup/Database.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations.IntegrationTests/Setup/Database.cs @@ -1,6 +1,6 @@ -using Microsoft.Data.SqlClient; +using System; +using Microsoft.Data.SqlClient; using RepoDb.SqlServer.BulkOperations.IntegrationTests.Models; -using System; namespace RepoDb.IntegrationTests.Setup { @@ -15,15 +15,23 @@ public static class Database public static void Initialize() { // Master connection - ConnectionStringForMaster = Environment.GetEnvironmentVariable("REPODB_CONSTR_MASTER", EnvironmentVariableTarget.Process) ?? - @"Server=(local);Database=master;Integrated Security=SSPI;TrustServerCertificate=True;"; + ConnectionStringForMaster = + Environment.GetEnvironmentVariable("REPODB_SQLSERVER_CONSTR_MASTER") + ?? Environment.GetEnvironmentVariable("REPODB_CONSTR_MASTER") + // ?? @"Server=tcp:127.0.0.1,41433;Database=master;User ID=sa;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;TrustServerCertificate=True;" // Docker Test Configuration + ?? @"Server=(local);Database=master;Integrated Security=SSPI;TrustServerCertificate=True;"; // RepoDb connection - ConnectionStringForRepoDb = Environment.GetEnvironmentVariable("REPODB_CONSTR", EnvironmentVariableTarget.Process) ?? - @"Server=(local);Database=RepoDb;Integrated Security=SSPI;TrustServerCertificate=True;"; + ConnectionStringForRepoDb = + Environment.GetEnvironmentVariable("REPODB_SQLSERVER_CONSTR_REPODBTEST") + ?? Environment.GetEnvironmentVariable("REPODB_CONSTR") + // ?? @"Server=tcp:127.0.0.1,41433;Database=RepoDbTest;User ID=sa;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;TrustServerCertificate=True;" // Docker Test Configuration + ?? @"Server=(local);Database=RepoDbTest;Integrated Security=SSPI;TrustServerCertificate=True;"; // Initialize the SqlServer - GlobalConfiguration.Setup().UseSqlServer(); + GlobalConfiguration + .Setup() + .UseSqlServer(); // Create the database first CreateDatabase(); @@ -49,9 +57,9 @@ public static void Initialize() /// public static void CreateDatabase() { - var commandText = @"IF (NOT EXISTS(SELECT * FROM sys.databases WHERE name = 'RepoDb')) + var commandText = @"IF (NOT EXISTS(SELECT * FROM sys.databases WHERE name = 'RepoDbTest')) BEGIN - CREATE DATABASE [RepoDb]; + CREATE DATABASE [RepoDbTest]; END"; using (var connection = new SqlConnection(ConnectionStringForMaster).EnsureOpen()) { diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/BulkDelete.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/BulkDelete.cs index 0d0fbd7ea..bf072bd11 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/BulkDelete.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/BulkDelete.cs @@ -1,6 +1,4 @@ -using RepoDb.Extensions; -using RepoDb.SqlServer.BulkOperations; -using System; +using System; using System.Collections.Generic; using System.Data; using System.Data.Common; @@ -8,6 +6,9 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Data.SqlClient; +using RepoDb.Extensions; +using RepoDb.Interfaces; +using RepoDb.SqlServer.BulkOperations; namespace RepoDb { @@ -26,15 +27,17 @@ public static partial class SqlConnectionExtension /// /// /// + /// /// internal static int BulkDeleteInternalBase(SqlConnection connection, string tableName, IEnumerable primaryKeys, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null) { // Validate if (primaryKeys?.Any() != true) @@ -75,7 +78,7 @@ internal static int BulkDeleteInternalBase(SqlConnection connection, primaryOrIdentityField.AsEnumerable(), dbSetting, false); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); // Do the bulk insertion first using (var dataTable = CreateDataTableWithSingleColumn(primaryOrIdentityField, primaryKeys)) @@ -101,7 +104,7 @@ internal static int BulkDeleteInternalBase(SqlConnection connection, sql = GetCreateTemporaryTableClusteredIndexSqlText(tempTableName, primaryOrIdentityField.AsEnumerable(), dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); // Delete the actual delete sql = GetBulkDeleteSqlText(tableName, @@ -113,7 +116,7 @@ internal static int BulkDeleteInternalBase(SqlConnection connection, // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); CommitTransaction(transaction, hasTransaction); } @@ -126,7 +129,7 @@ internal static int BulkDeleteInternalBase(SqlConnection connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } @@ -145,18 +148,20 @@ internal static int BulkDeleteInternalBase(SqlConnection connection, /// /// /// + /// /// internal static int BulkDeleteInternalBase(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null) { // Validate if (!reader.HasRows) @@ -234,16 +239,16 @@ internal static int BulkDeleteInternalBase(SqlConnection connection, fields, dbSetting, false); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); - // Set the options to KeepIdentity if needed - if (Equals(options, default(SqlBulkCopyOptions)) && - identityDbField?.IsIdentity == true && - fields?.FirstOrDefault( - field => string.Equals(field.Name, identityDbField.Name, StringComparison.OrdinalIgnoreCase)) != null) - { - options = Compiler.GetEnumFunc("KeepIdentity")(); - } + //// Set the options to KeepIdentity if needed + //if (options == SqlBulkCopyOptions.Default && + // identityDbField?.IsIdentity == true && + // fields?.FirstOrDefault( + // field => string.Equals(field.Name, identityDbField.Name, StringComparison.OrdinalIgnoreCase)) != null) + //{ + // options = SqlBulkCopyOptions.KeepIdentity; + //} // If there is no mapping if (mappings?.Any() != true) @@ -265,7 +270,7 @@ internal static int BulkDeleteInternalBase(SqlConnection connection, sql = GetCreateTemporaryTableClusteredIndexSqlText(tempTableName, qualifiers, dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); // Delete the actual delete sql = GetBulkDeleteSqlText(tableName, @@ -277,7 +282,7 @@ internal static int BulkDeleteInternalBase(SqlConnection connection, // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); CommitTransaction(transaction, hasTransaction); } @@ -290,7 +295,7 @@ internal static int BulkDeleteInternalBase(SqlConnection connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } @@ -310,19 +315,21 @@ internal static int BulkDeleteInternalBase(SqlConnection connection, /// /// /// + /// /// internal static int BulkDeleteInternalBase(SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null) { // Validate if (dataTable?.Rows.Count <= 0) @@ -400,16 +407,16 @@ internal static int BulkDeleteInternalBase(SqlConnection connection, fields, dbSetting, false); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); - // Set the options to KeepIdentity if needed - if (Equals(options, default(SqlBulkCopyOptions)) && - identityDbField?.IsIdentity == true && - fields?.FirstOrDefault( - field => string.Equals(field.Name, identityDbField.Name, StringComparison.OrdinalIgnoreCase)) != null) - { - options = Compiler.GetEnumFunc("KeepIdentity")(); - } + //// Set the options to KeepIdentity if needed + //if (options == SqlBulkCopyOptions.Default && + // identityDbField?.IsIdentity == true && + // fields?.FirstOrDefault( + // field => string.Equals(field.Name, identityDbField.Name, StringComparison.OrdinalIgnoreCase)) != null) + //{ + // options = SqlBulkCopyOptions.KeepIdentity; + //} // If there is no mapping if (mappings?.Any() != true) @@ -433,7 +440,7 @@ internal static int BulkDeleteInternalBase(SqlConnection connection, sql = GetCreateTemporaryTableClusteredIndexSqlText(tempTableName, qualifiers, dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); // Delete the actual delete sql = GetBulkDeleteSqlText(tableName, @@ -445,7 +452,7 @@ internal static int BulkDeleteInternalBase(SqlConnection connection, // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); CommitTransaction(transaction, hasTransaction); } @@ -458,7 +465,7 @@ internal static int BulkDeleteInternalBase(SqlConnection connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } @@ -479,15 +486,17 @@ internal static int BulkDeleteInternalBase(SqlConnection connection, /// /// /// + /// /// internal static async Task BulkDeleteAsyncInternalBase(SqlConnection connection, string tableName, IEnumerable primaryKeys, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) { // Validate @@ -527,7 +536,7 @@ internal static async Task BulkDeleteAsyncInternalBase(SqlConnection connec primaryOrIdentityField.AsEnumerable(), dbSetting, false); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); // Do the bulk insertion first using (var dataTable = CreateDataTableWithSingleColumn(primaryOrIdentityField, primaryKeys)) @@ -554,7 +563,7 @@ await WriteToServerAsyncInternal(connection, sql = GetCreateTemporaryTableClusteredIndexSqlText(tempTableName, primaryOrIdentityField.AsEnumerable(), dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); // Delete the actual delete sql = GetBulkDeleteSqlText(tableName, @@ -566,7 +575,7 @@ await WriteToServerAsyncInternal(connection, // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); CommitTransaction(transaction, hasTransaction); } @@ -579,7 +588,7 @@ await WriteToServerAsyncInternal(connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } @@ -598,19 +607,21 @@ await WriteToServerAsyncInternal(connection, /// /// /// + /// /// /// internal static async Task BulkDeleteAsyncInternalBase(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) { // Validate @@ -689,16 +700,16 @@ internal static async Task BulkDeleteAsyncInternalBase(SqlConnection connec fields, dbSetting, false); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); - // Set the options to KeepIdentity if needed - if (Equals(options, default(SqlBulkCopyOptions)) && - identityDbField?.IsIdentity == true && - fields?.FirstOrDefault( - field => string.Equals(field.Name, identityDbField.Name, StringComparison.OrdinalIgnoreCase)) != null) - { - options = Compiler.GetEnumFunc("KeepIdentity")(); - } + //// Set the options to KeepIdentity if needed + //if (options == SqlBulkCopyOptions.Default && + // identityDbField?.IsIdentity == true && + // fields?.FirstOrDefault( + // field => string.Equals(field.Name, identityDbField.Name, StringComparison.OrdinalIgnoreCase)) != null) + //{ + // options = SqlBulkCopyOptions.KeepIdentity; + //} // If there is no mapping if (mappings?.Any() != true) @@ -721,7 +732,7 @@ await WriteToServerAsyncInternal(connection, sql = GetCreateTemporaryTableClusteredIndexSqlText(tempTableName, qualifiers, dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); // Delete the actual delete sql = GetBulkDeleteSqlText(tableName, @@ -733,7 +744,7 @@ await WriteToServerAsyncInternal(connection, // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); CommitTransaction(transaction, hasTransaction); } @@ -746,7 +757,7 @@ await WriteToServerAsyncInternal(connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } @@ -766,20 +777,22 @@ await WriteToServerAsyncInternal(connection, /// /// /// + /// /// /// internal static async Task BulkDeleteAsyncInternalBase(SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) { // Validate @@ -858,16 +871,16 @@ internal static async Task BulkDeleteAsyncInternalBase(SqlConnection connec fields, dbSetting, false); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); - // Set the options to KeepIdentity if needed - if (Equals(options, default(SqlBulkCopyOptions)) && - identityDbField?.IsIdentity == true && - fields?.FirstOrDefault( - field => string.Equals(field.Name, identityDbField.Name, StringComparison.OrdinalIgnoreCase)) != null) - { - options = Compiler.GetEnumFunc("KeepIdentity")(); - } + //// Set the options to KeepIdentity if needed + //if (options == SqlBulkCopyOptions.Default && + // identityDbField?.IsIdentity == true && + // fields?.FirstOrDefault( + // field => string.Equals(field.Name, identityDbField.Name, StringComparison.OrdinalIgnoreCase)) != null) + //{ + // options = SqlBulkCopyOptions.KeepIdentity; + //} // If there is no mapping if (mappings?.Any() != true) @@ -892,7 +905,7 @@ await WriteToServerAsyncInternal(connection, sql = GetCreateTemporaryTableClusteredIndexSqlText(tempTableName, qualifiers, dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); // Delete the actual delete sql = GetBulkDeleteSqlText(tableName, @@ -904,7 +917,7 @@ await WriteToServerAsyncInternal(connection, // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); CommitTransaction(transaction, hasTransaction); } @@ -917,7 +930,7 @@ await WriteToServerAsyncInternal(connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/BulkInsert.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/BulkInsert.cs index 13670613b..0102ffc2b 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/BulkInsert.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/BulkInsert.cs @@ -1,5 +1,4 @@ -using RepoDb.Extensions; -using System; +using System; using System.Collections.Generic; using System.Data; using System.Data.Common; @@ -7,6 +6,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Data.SqlClient; +using RepoDb.Extensions; using RepoDb.Interfaces; namespace RepoDb @@ -30,18 +30,20 @@ public static partial class SqlConnectionExtension /// /// /// + /// /// private static int BulkInsertInternalBase(SqlConnection connection, string tableName, IEnumerable entities, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null) where TEntity : class { // Validate @@ -140,7 +142,7 @@ private static int BulkInsertInternalBase(SqlConnection connection, // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); } CommitTransaction(transaction, hasTransaction); @@ -154,7 +156,7 @@ private static int BulkInsertInternalBase(SqlConnection connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } @@ -174,11 +176,11 @@ private static int BulkInsertInternalBase(SqlConnection connection, internal static int BulkInsertInternalBase(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, int? bulkCopyTimeout = null, int? batchSize = null, - SqlTransaction transaction = null) + SqlTransaction? transaction = null) { // Validate if (!reader.HasRows) @@ -253,7 +255,7 @@ internal static int BulkInsertInternalBase(SqlConnection connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } @@ -273,19 +275,21 @@ internal static int BulkInsertInternalBase(SqlConnection connection, /// /// /// + /// /// internal static int BulkInsertInternalBase(SqlConnection connection, string tableName, DataTable dataTable, DataRowState? rowState = null, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null) { // Validate if (dataTable?.Rows.Count <= 0) @@ -391,7 +395,7 @@ internal static int BulkInsertInternalBase(SqlConnection connection, // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); } } @@ -406,7 +410,7 @@ internal static int BulkInsertInternalBase(SqlConnection connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } @@ -430,19 +434,21 @@ internal static int BulkInsertInternalBase(SqlConnection connection, /// /// /// + /// /// /// private static async Task BulkInsertAsyncInternalBase(SqlConnection connection, string tableName, IEnumerable entities, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -545,7 +551,7 @@ private static async Task BulkInsertAsyncInternalBase(SqlConnectio // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); } CommitTransaction(transaction, hasTransaction); @@ -559,11 +565,11 @@ private static async Task BulkInsertAsyncInternalBase(SqlConnectio { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } - + /// /// /// @@ -580,11 +586,11 @@ private static async Task BulkInsertAsyncInternalBase(SqlConnectio internal static async Task BulkInsertAsyncInternalBase(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, int? bulkCopyTimeout = null, int? batchSize = null, - SqlTransaction transaction = null, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { // Validate @@ -661,7 +667,7 @@ internal static async Task BulkInsertAsyncInternalBase(SqlConnection connec { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } @@ -681,20 +687,22 @@ internal static async Task BulkInsertAsyncInternalBase(SqlConnection connec /// /// /// + /// /// /// internal static async Task BulkInsertAsyncInternalBase(SqlConnection connection, string tableName, DataTable dataTable, DataRowState? rowState = null, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) { // Validate @@ -752,7 +760,7 @@ internal static async Task BulkInsertAsyncInternalBase(SqlConnection connec // Pseudo temp table var withPseudoExecution = isReturnIdentity == true && identityDbField != null; - var tempTableName = await CreateBulkInsertTempTableIfNecessaryAsync(connection, + var tempTableName = await CreateBulkInsertTempTableIfNecessaryAsync(connection, tableName, usePhysicalPseudoTempTable, transaction, @@ -803,7 +811,7 @@ internal static async Task BulkInsertAsyncInternalBase(SqlConnection connec // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); } } @@ -818,13 +826,13 @@ internal static async Task BulkInsertAsyncInternalBase(SqlConnection connec { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } #endregion - + private static string CreateBulkInsertTempTableIfNecessary( IDbConnection connection, string tableName, @@ -832,16 +840,17 @@ private static string CreateBulkInsertTempTableIfNecessary( TSqlTransaction transaction, bool withPseudoExecution, IDbSetting dbSetting, - IEnumerable fields) + IEnumerable fields, + ITrace? trace = null) where TSqlTransaction : DbTransaction { - if (withPseudoExecution == false) + if (withPseudoExecution == false) return null; var tempTableName = CreateBulkInsertTempTableName(tableName, usePhysicalPseudoTempTable, dbSetting); var sql = GetCreateTemporaryTableSqlText(tableName, tempTableName, fields, dbSetting, true); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); return tempTableName; } @@ -852,17 +861,18 @@ private static async Task CreateBulkInsertTempTableIfNecessaryAsync fields, - CancellationToken cancellationToken) + IEnumerable fields, + CancellationToken cancellationToken, + ITrace? trace = null) where TSqlTransaction : DbTransaction { - if (withPseudoExecution == false) + if (withPseudoExecution == false) return null; var tempTableName = CreateBulkInsertTempTableName(tableName, usePhysicalPseudoTempTable, dbSetting); var sql = GetCreateTemporaryTableSqlText(tableName, tempTableName, fields, dbSetting, true); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); return tempTableName; } diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/BulkMerge.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/BulkMerge.cs index ead9a492b..2cd3962ab 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/BulkMerge.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/BulkMerge.cs @@ -1,6 +1,4 @@ -using RepoDb.Extensions; -using RepoDb.SqlServer.BulkOperations; -using System; +using System; using System.Collections.Generic; using System.Data; using System.Data.Common; @@ -8,6 +6,8 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Data.SqlClient; +using RepoDb.Extensions; +using RepoDb.Interfaces; namespace RepoDb { @@ -31,19 +31,21 @@ public static partial class SqlConnectionExtension /// /// /// + /// /// private static int BulkMergeInternalBase(SqlConnection connection, string tableName, IEnumerable entities, - IEnumerable qualifiers = null, - IEnumerable mappings = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null) where TEntity : class { // Validate @@ -124,18 +126,18 @@ private static int BulkMergeInternalBase(SqlConnection connection, fields, dbSetting, hasOrderingColumn); - connection.ExecuteNonQuery(sql, transaction: transaction); - - // Set the options to KeepIdentity if needed - if (Equals(options, default(SqlBulkCopyOptions)) && - identityDbField?.IsIdentity == true && - qualifiers?.Any( - field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true && - fields?.Any( - field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true) - { - options = Compiler.GetEnumFunc("KeepIdentity")(); - } + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); + + //// Set the options to KeepIdentity if needed + //if (options == SqlBulkCopyOptions.Default && + // identityDbField?.IsIdentity == true && + // qualifiers?.Any( + // field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true && + // fields?.Any( + // field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true) + //{ + // options = SqlBulkCopyOptions.KeepIdentity; + //} // WriteToServer WriteToServerInternal(connection, @@ -146,13 +148,14 @@ private static int BulkMergeInternalBase(SqlConnection connection, bulkCopyTimeout, batchSize, hasOrderingColumn, - transaction); + transaction, + trace); // Create the clustered index sql = GetCreateTemporaryTableClusteredIndexSqlText(tempTableName, qualifiers, dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); // Merge the actual merge sql = GetBulkMergeSqlText(tableName, @@ -163,17 +166,17 @@ private static int BulkMergeInternalBase(SqlConnection connection, identityDbField?.AsField(), hints, dbSetting, - isReturnIdentity.GetValueOrDefault(), + isReturnIdentity, options.HasFlag(SqlBulkCopyOptions.KeepIdentity)); // Identity if the identity is to return if (hasOrderingColumn != true || TypeCache.Get(entityType).IsAnonymousType()) { - result = connection.ExecuteNonQuery(sql, commandTimeout: bulkCopyTimeout, transaction: transaction); + result = connection.ExecuteNonQuery(sql, commandTimeout: bulkCopyTimeout, transaction: transaction, trace: trace); } else { - using var reader = (DbDataReader)connection.ExecuteReader(sql, commandTimeout: bulkCopyTimeout, transaction: transaction); + using var reader = (DbDataReader)connection.ExecuteReader(sql, commandTimeout: bulkCopyTimeout, transaction: transaction, trace: trace); var mapping = mappings?.FirstOrDefault(e => string.Equals(e.DestinationColumn, identityDbField.Name, StringComparison.OrdinalIgnoreCase)); var identityField = mapping != null ? new Field(mapping.SourceColumn) : identityDbField.AsField(); @@ -182,7 +185,7 @@ private static int BulkMergeInternalBase(SqlConnection connection, // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); CommitTransaction(transaction, hasTransaction); } @@ -195,7 +198,7 @@ private static int BulkMergeInternalBase(SqlConnection connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } @@ -214,18 +217,20 @@ private static int BulkMergeInternalBase(SqlConnection connection, /// /// /// + /// /// private static int BulkMergeInternalBase(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null) { // Validate if (!reader.HasRows) @@ -303,18 +308,18 @@ private static int BulkMergeInternalBase(SqlConnection connection, fields, dbSetting, false); - connection.ExecuteNonQuery(sql, transaction: transaction); - - // Set the options to KeepIdentity if needed - if (Equals(options, default(SqlBulkCopyOptions)) && - identityDbField?.IsIdentity == true && - qualifiers?.Any( - field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true && - fields?.Any( - field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true) - { - options = Compiler.GetEnumFunc("KeepIdentity")(); - } + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); + + //// Set the options to KeepIdentity if needed + //if (options == SqlBulkCopyOptions.Default && + // identityDbField?.IsIdentity == true && + // qualifiers?.Any( + // field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true && + // fields?.Any( + // field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true) + //{ + // options = SqlBulkCopyOptions.KeepIdentity; + //} // WriteToServer WriteToServerInternal(connection, @@ -330,7 +335,7 @@ private static int BulkMergeInternalBase(SqlConnection connection, sql = GetCreateTemporaryTableClusteredIndexSqlText(tempTableName, qualifiers, dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); // Merge the actual merge sql = GetBulkMergeSqlText(tableName, @@ -347,7 +352,7 @@ private static int BulkMergeInternalBase(SqlConnection connection, // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); CommitTransaction(transaction, hasTransaction); } @@ -360,7 +365,7 @@ private static int BulkMergeInternalBase(SqlConnection connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } @@ -381,20 +386,22 @@ private static int BulkMergeInternalBase(SqlConnection connection, /// /// /// + /// /// private static int BulkMergeInternalBase(SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null) { // Validate if (dataTable?.Rows.Count <= 0) @@ -473,18 +480,18 @@ private static int BulkMergeInternalBase(SqlConnection connection, fields, dbSetting, hasOrderingColumn); - connection.ExecuteNonQuery(sql, transaction: transaction); - - // Set the options to KeepIdentity if needed - if (Equals(options, default(SqlBulkCopyOptions)) && - identityDbField?.IsIdentity == true && - qualifiers?.Any( - field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true && - fields?.Any( - field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true) - { - options = Compiler.GetEnumFunc("KeepIdentity")(); - } + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); + + //// Set the options to KeepIdentity if needed + //if (options == SqlBulkCopyOptions.Default && + // identityDbField?.IsIdentity == true && + // qualifiers?.Any( + // field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true && + // fields?.Any( + // field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true) + //{ + // options = SqlBulkCopyOptions.KeepIdentity; + //} // WriteToServer WriteToServerInternal(connection, @@ -502,7 +509,7 @@ private static int BulkMergeInternalBase(SqlConnection connection, sql = GetCreateTemporaryTableClusteredIndexSqlText(tempTableName, qualifiers, dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); // Merge the actual merge sql = GetBulkMergeSqlText(tableName, @@ -513,7 +520,7 @@ private static int BulkMergeInternalBase(SqlConnection connection, identityDbField?.AsField(), hints, dbSetting, - isReturnIdentity.GetValueOrDefault(), + isReturnIdentity, options.HasFlag(SqlBulkCopyOptions.KeepIdentity)); // Identity if the identity is to return @@ -536,7 +543,7 @@ private static int BulkMergeInternalBase(SqlConnection connection, // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); CommitTransaction(transaction, hasTransaction); } @@ -549,7 +556,7 @@ private static int BulkMergeInternalBase(SqlConnection connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } @@ -574,20 +581,22 @@ private static int BulkMergeInternalBase(SqlConnection connection, /// /// /// + /// /// /// private static async Task BulkMergeAsyncInternalBase(SqlConnection connection, string tableName, IEnumerable entities, - IEnumerable qualifiers = null, - IEnumerable mappings = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -669,18 +678,18 @@ private static async Task BulkMergeAsyncInternalBase(SqlConnection fields, dbSetting, hasOrderingColumn); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); - - // Set the options to KeepIdentity if needed - if (Equals(options, default(SqlBulkCopyOptions)) && - identityDbField?.IsIdentity == true && - qualifiers?.Any( - field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true && - fields?.Any( - field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true) - { - options = Compiler.GetEnumFunc("KeepIdentity")(); - } + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); + + //// Set the options to KeepIdentity if needed + //if (options == SqlBulkCopyOptions.Default && + // identityDbField?.IsIdentity == true && + // qualifiers?.Any( + // field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true && + // fields?.Any( + // field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true) + //{ + // options = SqlBulkCopyOptions.KeepIdentity; + //} // WriteToServer await WriteToServerAsyncInternal(connection, @@ -698,7 +707,7 @@ await WriteToServerAsyncInternal(connection, sql = GetCreateTemporaryTableClusteredIndexSqlText(tempTableName, qualifiers, dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); // Merge the actual merge sql = GetBulkMergeSqlText(tableName, @@ -709,14 +718,14 @@ await WriteToServerAsyncInternal(connection, identityDbField?.AsField(), hints, dbSetting, - isReturnIdentity.GetValueOrDefault(), + isReturnIdentity, options.HasFlag(SqlBulkCopyOptions.KeepIdentity)); // Identity if the identity is to return if (hasOrderingColumn != true || TypeCache.Get(entityType).IsAnonymousType()) { result = await connection.ExecuteNonQueryAsync(sql, commandTimeout: bulkCopyTimeout, - transaction: transaction, cancellationToken: cancellationToken); + transaction: transaction, trace: trace, cancellationToken: cancellationToken); } else { @@ -727,7 +736,7 @@ await WriteToServerAsyncInternal(connection, // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); CommitTransaction(transaction, hasTransaction); } @@ -740,7 +749,7 @@ await WriteToServerAsyncInternal(connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } @@ -759,19 +768,21 @@ await WriteToServerAsyncInternal(connection, /// /// /// + /// /// /// private static async Task BulkMergeAsyncInternalBase(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) { // Validate @@ -850,18 +861,18 @@ private static async Task BulkMergeAsyncInternalBase(SqlConnection connecti fields, dbSetting, false); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); - - // Set the options to KeepIdentity if needed - if (Equals(options, default(SqlBulkCopyOptions)) && - identityDbField?.IsIdentity == true && - qualifiers?.Any( - field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true && - fields?.Any( - field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true) - { - options = Compiler.GetEnumFunc("KeepIdentity")(); - } + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); + + //// Set the options to KeepIdentity if needed + //if (options == SqlBulkCopyOptions.Default && + // identityDbField?.IsIdentity == true && + // qualifiers?.Any( + // field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true && + // fields?.Any( + // field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true) + //{ + // options = SqlBulkCopyOptions.KeepIdentity; + //} // WriteToServer await WriteToServerAsyncInternal(connection, @@ -878,7 +889,7 @@ await WriteToServerAsyncInternal(connection, sql = GetCreateTemporaryTableClusteredIndexSqlText(tempTableName, qualifiers, dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); // Merge the actual merge sql = GetBulkMergeSqlText(tableName, @@ -891,11 +902,11 @@ await WriteToServerAsyncInternal(connection, dbSetting, false, options.HasFlag(SqlBulkCopyOptions.KeepIdentity)); - result = await connection.ExecuteNonQueryAsync(sql, commandTimeout: bulkCopyTimeout, transaction: transaction, cancellationToken: cancellationToken); + result = await connection.ExecuteNonQueryAsync(sql, commandTimeout: bulkCopyTimeout, transaction: transaction, trace: trace, cancellationToken: cancellationToken); // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); CommitTransaction(transaction, hasTransaction); } @@ -908,7 +919,7 @@ await WriteToServerAsyncInternal(connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } @@ -930,20 +941,22 @@ await WriteToServerAsyncInternal(connection, /// /// /// + /// /// private static async Task BulkMergeAsyncInternalBase(SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) { // Validate @@ -1023,7 +1036,7 @@ private static async Task BulkMergeAsyncInternalBase(SqlConnection connecti fields, dbSetting, hasOrderingColumn); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); // WriteToServer await WriteToServerAsyncInternal(connection, @@ -1042,18 +1055,18 @@ await WriteToServerAsyncInternal(connection, sql = GetCreateTemporaryTableClusteredIndexSqlText(tempTableName, qualifiers, dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); - - // Set the options to KeepIdentity if needed - if (Equals(options, default(SqlBulkCopyOptions)) && - identityDbField?.IsIdentity == true && - qualifiers?.Any( - field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true && - fields?.Any( - field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true) - { - options = Compiler.GetEnumFunc("KeepIdentity")(); - } + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); + + //// Set the options to KeepIdentity if needed + //if (options == SqlBulkCopyOptions.Default && + // identityDbField?.IsIdentity == true && + // qualifiers?.Any( + // field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true && + // fields?.Any( + // field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true) + //{ + // options = SqlBulkCopyOptions.KeepIdentity; + //} // Merge the actual merge sql = GetBulkMergeSqlText(tableName, @@ -1064,7 +1077,7 @@ await WriteToServerAsyncInternal(connection, identityDbField?.AsField(), hints, dbSetting, - isReturnIdentity.GetValueOrDefault(), + isReturnIdentity, options.HasFlag(SqlBulkCopyOptions.KeepIdentity)); // Identity if the identity is to return @@ -1087,7 +1100,7 @@ await WriteToServerAsyncInternal(connection, // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); CommitTransaction(transaction, hasTransaction); } @@ -1100,7 +1113,7 @@ await WriteToServerAsyncInternal(connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/BulkUpdate.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/BulkUpdate.cs index 135ce67c4..c7e46ac23 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/BulkUpdate.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/BulkUpdate.cs @@ -1,6 +1,4 @@ -using RepoDb.Extensions; -using RepoDb.SqlServer.BulkOperations; -using System; +using System; using System.Collections.Generic; using System.Data; using System.Data.Common; @@ -8,6 +6,8 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Data.SqlClient; +using RepoDb.Extensions; +using RepoDb.Interfaces; namespace RepoDb { @@ -29,18 +29,20 @@ public static partial class SqlConnectionExtension /// /// /// + /// /// internal static int BulkUpdateInternalBase(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null) { // Validate if (!reader.HasRows) @@ -118,18 +120,18 @@ internal static int BulkUpdateInternalBase(SqlConnection connection, fields, dbSetting, false); - connection.ExecuteNonQuery(sql, transaction: transaction); - - // Set the options to KeepIdentity if needed - if (Equals(options, default(SqlBulkCopyOptions)) && - identityDbField?.IsIdentity == true && - qualifiers?.Any( - field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true && - fields?.Any( - field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true) - { - options = Compiler.GetEnumFunc("KeepIdentity")(); - } + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); + + //// Set the options to KeepIdentity if needed + //if (options == SqlBulkCopyOptions.Default && + // identityDbField?.IsIdentity == true && + // qualifiers?.Any( + // field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true && + // fields?.Any( + // field => string.Equals(field.Name, identityDbField?.Name, StringComparison.OrdinalIgnoreCase)) == true) + //{ + // options = SqlBulkCopyOptions.KeepIdentity; + //} // WriteToServer WriteToServerInternal(connection, @@ -145,7 +147,7 @@ internal static int BulkUpdateInternalBase(SqlConnection connection, sql = GetCreateTemporaryTableClusteredIndexSqlText(tempTableName, qualifiers, dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); // Update the actual update sql = GetBulkUpdateSqlText(tableName, @@ -160,7 +162,7 @@ internal static int BulkUpdateInternalBase(SqlConnection connection, // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); CommitTransaction(transaction, hasTransaction); } @@ -173,7 +175,7 @@ internal static int BulkUpdateInternalBase(SqlConnection connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } @@ -193,19 +195,21 @@ internal static int BulkUpdateInternalBase(SqlConnection connection, /// The size per batch to be used. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// /// The number of rows affected by the execution. internal static int BulkUpdateInternalBase(SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null) { // Validate if (dataTable?.Rows.Count <= 0) @@ -283,16 +287,16 @@ internal static int BulkUpdateInternalBase(SqlConnection connection, fields, dbSetting, false); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); - // Set the options to KeepIdentity if needed - if (Equals(options, default(SqlBulkCopyOptions)) && - identityDbField?.IsIdentity == true && - fields?.FirstOrDefault( - field => string.Equals(field.Name, identityDbField.Name, StringComparison.OrdinalIgnoreCase)) != null) - { - options = Compiler.GetEnumFunc("KeepIdentity")(); - } + //// Set the options to KeepIdentity if needed + //if (options == SqlBulkCopyOptions.Default && + // identityDbField?.IsIdentity == true && + // fields?.FirstOrDefault( + // field => string.Equals(field.Name, identityDbField.Name, StringComparison.OrdinalIgnoreCase)) != null) + //{ + // options = SqlBulkCopyOptions.KeepIdentity; + //} // WriteToServer WriteToServerInternal(connection, @@ -310,7 +314,7 @@ internal static int BulkUpdateInternalBase(SqlConnection connection, sql = GetCreateTemporaryTableClusteredIndexSqlText(tempTableName, qualifiers, dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); // Update the actual update sql = GetBulkUpdateSqlText(tableName, @@ -325,7 +329,7 @@ internal static int BulkUpdateInternalBase(SqlConnection connection, // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - connection.ExecuteNonQuery(sql, transaction: transaction); + connection.ExecuteNonQuery(sql, transaction: transaction, trace: trace); CommitTransaction(transaction, hasTransaction); } @@ -338,7 +342,7 @@ internal static int BulkUpdateInternalBase(SqlConnection connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } @@ -361,19 +365,21 @@ internal static int BulkUpdateInternalBase(SqlConnection connection, /// /// /// + /// /// /// internal static async Task BulkUpdateAsyncInternalBase(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) { // Validate @@ -452,16 +458,16 @@ internal static async Task BulkUpdateAsyncInternalBase(SqlConnection connec fields, dbSetting, false); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); - // Set the options to KeepIdentity if needed - if (Equals(options, default(SqlBulkCopyOptions)) && - identityDbField?.IsIdentity == true && - fields?.FirstOrDefault( - field => string.Equals(field.Name, identityDbField.Name, StringComparison.OrdinalIgnoreCase)) != null) - { - options = Compiler.GetEnumFunc("KeepIdentity")(); - } + //// Set the options to KeepIdentity if needed + //if (options == SqlBulkCopyOptions.Default && + // identityDbField?.IsIdentity == true && + // fields?.FirstOrDefault( + // field => string.Equals(field.Name, identityDbField.Name, StringComparison.OrdinalIgnoreCase)) != null) + //{ + // options = SqlBulkCopyOptions.KeepIdentity; + //} // WriteToServer await WriteToServerAsyncInternal(connection, @@ -478,7 +484,7 @@ await WriteToServerAsyncInternal(connection, sql = GetCreateTemporaryTableClusteredIndexSqlText(tempTableName, qualifiers, dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); // Update the actual update sql = GetBulkUpdateSqlText(tableName, @@ -493,7 +499,7 @@ await WriteToServerAsyncInternal(connection, // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); CommitTransaction(transaction, hasTransaction); } @@ -506,7 +512,7 @@ await WriteToServerAsyncInternal(connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } @@ -526,20 +532,22 @@ await WriteToServerAsyncInternal(connection, /// /// /// + /// /// /// internal static async Task BulkUpdateAsyncInternalBase(SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) { // Validate @@ -618,16 +626,16 @@ internal static async Task BulkUpdateAsyncInternalBase(SqlConnection connec fields, dbSetting, false); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); - // Set the options to KeepIdentity if needed - if (Equals(options, default(SqlBulkCopyOptions)) && - identityDbField?.IsIdentity == true && - fields?.FirstOrDefault( - field => string.Equals(field.Name, identityDbField.Name, StringComparison.OrdinalIgnoreCase)) != null) - { - options = Compiler.GetEnumFunc("KeepIdentity")(); - } + //// Set the options to KeepIdentity if needed + //if (options == SqlBulkCopyOptions.Default && + // identityDbField?.IsIdentity == true && + // fields?.FirstOrDefault( + // field => string.Equals(field.Name, identityDbField.Name, StringComparison.OrdinalIgnoreCase)) != null) + //{ + // options = SqlBulkCopyOptions.KeepIdentity; + //} // WriteToServer await WriteToServerAsyncInternal(connection, @@ -646,7 +654,7 @@ await WriteToServerAsyncInternal(connection, sql = GetCreateTemporaryTableClusteredIndexSqlText(tempTableName, qualifiers, dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); // Update the actual update sql = GetBulkUpdateSqlText(tableName, @@ -661,7 +669,7 @@ await WriteToServerAsyncInternal(connection, // Drop the table after used sql = GetDropTemporaryTableSqlText(tempTableName, dbSetting); - await connection.ExecuteNonQueryAsync(sql, transaction: transaction, cancellationToken: cancellationToken); + await connection.ExecuteNonQueryAsync(sql, transaction: transaction, trace: trace, cancellationToken: cancellationToken); CommitTransaction(transaction, hasTransaction); } @@ -674,7 +682,7 @@ await WriteToServerAsyncInternal(connection, { DisposeTransaction(transaction, hasTransaction); } - + // Return the result return result; } diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/WriteToServer.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/WriteToServer.cs index 96a3e4f1a..65baa0ecc 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/WriteToServer.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Base/WriteToServer.cs @@ -1,6 +1,4 @@ -using RepoDb.Exceptions; -using RepoDb.SqlServer.BulkOperations; -using System; +using System; using System.Collections.Generic; using System.Data; using System.Data.Common; @@ -8,6 +6,9 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Data.SqlClient; +using RepoDb.Exceptions; +using RepoDb.Interfaces; +using RepoDb.SqlServer.BulkOperations; namespace RepoDb { @@ -28,16 +29,18 @@ public static partial class SqlConnectionExtension /// /// /// + /// /// private static int WriteToServerInternal(SqlConnection connection, string tableName, IEnumerable entities, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, int? bulkCopyTimeout = null, int? batchSize = null, bool hasOrderingColumn = false, - SqlTransaction transaction = null) + SqlTransaction? transaction = null, + ITrace? trace = null) where TEntity : class { // Throw an error if there are no mappings @@ -114,11 +117,11 @@ private static int WriteToServerInternal(SqlConnection connection, private static int WriteToServerInternal(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, int? bulkCopyTimeout = null, int? batchSize = null, - SqlTransaction transaction = null) + SqlTransaction? transaction = null) { // Throw an error if there are no mappings if (mappings?.Any() != true) @@ -184,12 +187,12 @@ private static int WriteToServerInternal(SqlConnection connection, string tableName, DataTable dataTable, DataRowState? rowState = null, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, int? bulkCopyTimeout = null, int? batchSize = null, bool hasOrderingColumn = false, - SqlTransaction transaction = null) + SqlTransaction? transaction = null) { // Throw an error if there are no mappings if (mappings?.Any() != true) @@ -271,12 +274,12 @@ private static int WriteToServerInternal(SqlConnection connection, private static async Task WriteToServerAsyncInternal(SqlConnection connection, string tableName, IEnumerable entities, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, int? bulkCopyTimeout = null, int? batchSize = null, bool hasOrderingColumn = false, - SqlTransaction transaction = null, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -355,11 +358,11 @@ private static async Task WriteToServerAsyncInternal(SqlConnection private static async Task WriteToServerAsyncInternal(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, int? bulkCopyTimeout = null, int? batchSize = null, - SqlTransaction transaction = null, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { // Throw an error if there are no mappings @@ -426,12 +429,12 @@ private static async Task WriteToServerAsyncInternal(SqlConnection connecti string tableName, DataTable dataTable, DataRowState? rowState = null, - IEnumerable mappings = null, + IEnumerable? mappings = null, SqlBulkCopyOptions options = default, int? bulkCopyTimeout = null, int? batchSize = null, bool hasOrderingColumn = false, - SqlTransaction transaction = null, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { // Throw an error if there are no mappings diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/BaseRepository/BulkDelete.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/BaseRepository/BulkDelete.cs index 5a012e169..fea655849 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/BaseRepository/BulkDelete.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/BaseRepository/BulkDelete.cs @@ -1,9 +1,9 @@ -using Microsoft.Data.SqlClient; -using System; +using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using Microsoft.Data.SqlClient; namespace RepoDb { @@ -27,10 +27,10 @@ public static partial class BaseRepositoryExtension /// The number of rows affected by the execution. public static int BulkDelete(this BaseRepository repository, IEnumerable primaryKeys, - string hints = null, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { return repository.DbRepository.BulkDelete(primaryKeys: primaryKeys, @@ -56,13 +56,13 @@ public static int BulkDelete(this BaseRepositoryThe number of rows affected by the execution. public static int BulkDelete(this BaseRepository repository, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { return repository.DbRepository.BulkDelete(entities: entities, @@ -93,13 +93,13 @@ public static int BulkDelete(this BaseRepository(this BaseRepository repository, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { return repository.DbRepository.BulkDelete(tableName: tableName, @@ -131,10 +131,10 @@ public static int BulkDelete(this BaseRepositoryThe number of rows affected by the execution. public static Task BulkDeleteAsync(this BaseRepository repository, IEnumerable primaryKeys, - string hints = null, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -163,13 +163,13 @@ public static Task BulkDeleteAsync(this BaseRepositoryThe number of rows affected by the execution. public static Task BulkDeleteAsync(this BaseRepository repository, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -203,13 +203,13 @@ public static Task BulkDeleteAsync(this BaseRepository BulkDeleteAsync(this BaseRepository repository, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/BaseRepository/BulkInsert.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/BaseRepository/BulkInsert.cs index ab236957f..9db2c9829 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/BaseRepository/BulkInsert.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/BaseRepository/BulkInsert.cs @@ -1,7 +1,7 @@ -using Microsoft.Data.SqlClient; -using System.Collections.Generic; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using Microsoft.Data.SqlClient; namespace RepoDb { @@ -28,13 +28,13 @@ public static partial class BaseRepositoryExtension /// The number of rows affected by the execution. public static int BulkInsert(this BaseRepository repository, IEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { return repository.DbRepository.BulkInsert(entities: entities, @@ -65,13 +65,13 @@ public static int BulkInsert(this BaseRepository(this BaseRepository repository, string tableName, IEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { return repository.DbRepository.BulkInsert(tableName: tableName, @@ -106,13 +106,13 @@ public static int BulkInsert(this BaseRepositoryThe number of rows affected by the execution. public static Task BulkInsertAsync(this BaseRepository repository, IEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -146,13 +146,13 @@ public static Task BulkInsertAsync(this BaseRepository BulkInsertAsync(this BaseRepository repository, string tableName, IEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -167,8 +167,8 @@ public static Task BulkInsertAsync(this BaseRepository + + /// /// Bulk insert a list of data entity objects into the database in an asynchronous way. /// /// The type of the data entity object. @@ -185,13 +185,13 @@ public static Task BulkInsertAsync(this BaseRepositoryThe number of rows affected by the execution. public static Task BulkInsertAsync(this BaseRepository repository, IAsyncEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -225,13 +225,13 @@ public static Task BulkInsertAsync(this BaseRepository BulkInsertAsync(this BaseRepository repository, string tableName, IAsyncEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/BaseRepository/BulkMerge.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/BaseRepository/BulkMerge.cs index ac00c5f6f..67c48121a 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/BaseRepository/BulkMerge.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/BaseRepository/BulkMerge.cs @@ -1,9 +1,9 @@ -using Microsoft.Data.SqlClient; -using System; +using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using Microsoft.Data.SqlClient; namespace RepoDb { @@ -31,14 +31,14 @@ public static partial class BaseRepositoryExtension /// The number of rows affected by the execution. public static int BulkMerge(this BaseRepository repository, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { return repository.DbRepository.BulkMerge(entities: entities, @@ -71,14 +71,14 @@ public static int BulkMerge(this BaseRepository public static int BulkMerge(this BaseRepository repository, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { return repository.DbRepository.BulkMerge(tableName: tableName, @@ -115,14 +115,14 @@ public static int BulkMerge(this BaseRepository /// The number of rows affected by the execution. public static Task BulkMergeAsync(this BaseRepository repository, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -158,14 +158,14 @@ public static Task BulkMergeAsync(this BaseRepository BulkMergeAsync(this BaseRepository repository, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/BaseRepository/BulkUpdate.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/BaseRepository/BulkUpdate.cs index 205292526..0e4c2855d 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/BaseRepository/BulkUpdate.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/BaseRepository/BulkUpdate.cs @@ -1,9 +1,9 @@ -using Microsoft.Data.SqlClient; -using System; +using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using Microsoft.Data.SqlClient; namespace RepoDb { @@ -30,13 +30,13 @@ public static partial class BaseRepositoryExtension /// The number of rows affected by the execution. public static int BulkUpdate(this BaseRepository repository, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { return repository.DbRepository.BulkUpdate(entities: entities, @@ -67,13 +67,13 @@ public static int BulkUpdate(this BaseRepository(this BaseRepository repository, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { return repository.DbRepository.BulkUpdate(tableName: tableName, @@ -108,13 +108,13 @@ public static int BulkUpdate(this BaseRepositoryThe number of rows affected by the execution. public static Task BulkUpdateAsync(this BaseRepository repository, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -148,13 +148,13 @@ public static Task BulkUpdateAsync(this BaseRepository BulkUpdateAsync(this BaseRepository repository, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/DbRepository/BulkDelete.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/DbRepository/BulkDelete.cs index 3078e9a13..590a82b3c 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/DbRepository/BulkDelete.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/DbRepository/BulkDelete.cs @@ -1,11 +1,11 @@ -using Microsoft.Data.SqlClient; -using System; +using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using Microsoft.Data.SqlClient; namespace RepoDb { @@ -29,10 +29,10 @@ public static partial class DbRepositoryExtension /// The number of rows affected by the execution. public static int BulkDelete(this DbRepository repository, IEnumerable primaryKeys, - string hints = null, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { // Create a connection @@ -64,13 +64,13 @@ public static int BulkDelete(this DbRepository repositor /// The number of rows affected by the execution. public static int BulkDelete(this DbRepository repository, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { // Create a connection @@ -107,13 +107,13 @@ public static int BulkDelete(this DbRepository repositor public static int BulkDelete(this DbRepository repository, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { // Create a connection @@ -148,13 +148,13 @@ public static int BulkDelete(this DbRepository repositor /// The number of rows affected by the execution. public static int BulkDelete(this DbRepository repository, DbDataReader reader, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { // Create a connection @@ -189,14 +189,14 @@ public static int BulkDelete(this DbRepository repositor /// The number of rows affected by the execution. public static int BulkDelete(this DbRepository repository, DataTable dataTable, - Expression> qualifiers = null, + Expression>? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { // Create a connection @@ -233,10 +233,10 @@ public static int BulkDelete(this DbRepository repositor public static int BulkDelete(this DbRepository repository, string tableName, IEnumerable primaryKeys, - string hints = null, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) { // Create a connection using var bulkDbConnector = new BulkDbConnector(transaction, repository); @@ -268,13 +268,13 @@ public static int BulkDelete(this DbRepository repository, public static int BulkDelete(this DbRepository repository, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) { // Create a connection using var bulkDbConnector = new BulkDbConnector(transaction, repository); @@ -310,14 +310,14 @@ public static int BulkDelete(this DbRepository repository, public static int BulkDelete(this DbRepository repository, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) { // Create a connection using var bulkDbConnector = new BulkDbConnector(transaction, repository); @@ -354,10 +354,10 @@ public static int BulkDelete(this DbRepository repository, /// The number of rows affected by the execution. public static async Task BulkDeleteAsync(this DbRepository repository, IEnumerable primaryKeys, - string hints = null, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -391,13 +391,13 @@ public static async Task BulkDeleteAsync(this DbRepositoryThe number of rows affected by the execution. public static async Task BulkDeleteAsync(this DbRepository repository, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -436,13 +436,13 @@ public static async Task BulkDeleteAsync(this DbRepository BulkDeleteAsync(this DbRepository repository, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -480,13 +480,13 @@ public static async Task BulkDeleteAsync(this DbRepositoryThe number of rows affected by the execution. public static async Task BulkDeleteAsync(this DbRepository repository, DbDataReader reader, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -524,14 +524,14 @@ public static async Task BulkDeleteAsync(this DbRepositoryThe number of rows affected by the execution. public static async Task BulkDeleteAsync(this DbRepository repository, DataTable dataTable, - Expression> qualifiers = null, + Expression>? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -571,10 +571,10 @@ public static async Task BulkDeleteAsync(this DbRepository BulkDeleteAsync(this DbRepository repository, string tableName, IEnumerable primaryKeys, - string hints = null, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { // Create a connection @@ -609,13 +609,13 @@ public static async Task BulkDeleteAsync(this DbRepository r public static async Task BulkDeleteAsync(this DbRepository repository, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { // Create a connection @@ -654,14 +654,14 @@ public static async Task BulkDeleteAsync(this DbRepository r public static async Task BulkDeleteAsync(this DbRepository repository, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { // Create a connection diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/DbRepository/BulkInsert.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/DbRepository/BulkInsert.cs index 5f793d4c6..28cab375c 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/DbRepository/BulkInsert.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/DbRepository/BulkInsert.cs @@ -1,9 +1,9 @@ -using Microsoft.Data.SqlClient; -using System.Collections.Generic; +using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Threading; using System.Threading.Tasks; +using Microsoft.Data.SqlClient; namespace RepoDb { @@ -30,13 +30,13 @@ public static partial class DbRepositoryExtension /// The number of rows affected by the execution. public static int BulkInsert(this DbRepository repository, IEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { // Create a connection @@ -72,13 +72,13 @@ public static int BulkInsert(this DbRepository repositor public static int BulkInsert(this DbRepository repository, string tableName, IEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { // Create a connection @@ -97,7 +97,7 @@ public static int BulkInsert(this DbRepository repositor transaction: transaction); } - + /// /// Bulk insert an instance of object into the database. /// @@ -111,10 +111,10 @@ public static int BulkInsert(this DbRepository repositor /// The number of rows affected by the execution. public static int BulkInsert(this DbRepository repository, DbDataReader reader, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, int? batchSize = null, - SqlTransaction transaction = null) + SqlTransaction? transaction = null) where TEntity : class { // Create a connection @@ -147,10 +147,10 @@ public static int BulkInsert(this DbRepository repositor public static int BulkInsert(this DbRepository repository, string tableName, DbDataReader reader, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, int? batchSize = null, - SqlTransaction transaction = null) + SqlTransaction? transaction = null) { // Create a connection using var bulkDbConnector = new BulkDbConnector(transaction, repository); @@ -183,13 +183,13 @@ public static int BulkInsert(this DbRepository repository, public static int BulkInsert(this DbRepository repository, DataTable dataTable, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { // Create a connection @@ -227,13 +227,13 @@ public static int BulkInsert(this DbRepository repository, string tableName, DataTable dataTable, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) { // Create a connection using var bulkDbConnector = new BulkDbConnector(transaction, repository); @@ -273,13 +273,13 @@ public static int BulkInsert(this DbRepository repository, /// The number of rows affected by the execution. public static async Task BulkInsertAsync(this DbRepository repository, IEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -318,13 +318,13 @@ public static async Task BulkInsertAsync(this DbRepository BulkInsertAsync(this DbRepository repository, string tableName, IEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -344,8 +344,8 @@ public static async Task BulkInsertAsync(this DbRepository + + /// /// Bulk insert a list of data entity objects into the database in an asynchronous way. /// /// The type of the data entity object. @@ -362,13 +362,13 @@ public static async Task BulkInsertAsync(this DbRepositoryThe number of rows affected by the execution. public static async Task BulkInsertAsync(this DbRepository repository, IAsyncEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -407,13 +407,13 @@ public static async Task BulkInsertAsync(this DbRepository BulkInsertAsync(this DbRepository repository, string tableName, IAsyncEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -448,10 +448,10 @@ public static async Task BulkInsertAsync(this DbRepositoryThe number of rows affected by the execution. public static async Task BulkInsertAsync(this DbRepository repository, DbDataReader reader, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, int? batchSize = null, - SqlTransaction transaction = null, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -487,10 +487,10 @@ public static async Task BulkInsertAsync(this DbRepository BulkInsertAsync(this DbRepository repository, string tableName, DbDataReader reader, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, int? batchSize = null, - SqlTransaction transaction = null, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { // Create a connection @@ -526,13 +526,13 @@ public static async Task BulkInsertAsync(this DbRepository r public static async Task BulkInsertAsync(this DbRepository repository, DataTable dataTable, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -573,13 +573,13 @@ public static async Task BulkInsertAsync(this DbRepository r string tableName, DataTable dataTable, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { // Create a connection diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/DbRepository/BulkMerge.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/DbRepository/BulkMerge.cs index 58889b12e..08797c93c 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/DbRepository/BulkMerge.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/DbRepository/BulkMerge.cs @@ -1,11 +1,11 @@ -using Microsoft.Data.SqlClient; -using System; +using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using Microsoft.Data.SqlClient; namespace RepoDb { @@ -33,14 +33,14 @@ public static partial class DbRepositoryExtension /// The number of rows affected by the execution. public static int BulkMerge(this DbRepository repository, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { // Create a connection @@ -78,14 +78,14 @@ public static int BulkMerge(this DbRepository repository public static int BulkMerge(this DbRepository repository, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { // Create a connection @@ -121,13 +121,13 @@ public static int BulkMerge(this DbRepository repository /// The number of rows affected by the execution. public static int BulkMerge(this DbRepository repository, DbDataReader reader, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { // Create a connection @@ -166,13 +166,13 @@ public static int BulkMerge(this DbRepository repository public static int BulkMerge(this DbRepository repository, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) { // Create a connection using var bulkDbConnector = new BulkDbConnector(transaction, repository); @@ -208,15 +208,15 @@ public static int BulkMerge(this DbRepository repository, /// The number of rows affected by the execution. public static int BulkMerge(this DbRepository repository, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { // Create a connection @@ -255,15 +255,15 @@ public static int BulkMerge(this DbRepository repository public static int BulkMerge(this DbRepository repository, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) { // Create a connection using var bulkDbConnector = new BulkDbConnector(transaction, repository); @@ -305,14 +305,14 @@ public static int BulkMerge(this DbRepository repository, /// The number of rows affected by the execution. public static async Task BulkMergeAsync(this DbRepository repository, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -353,14 +353,14 @@ public static async Task BulkMergeAsync(this DbRepository BulkMergeAsync(this DbRepository repository, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -399,13 +399,13 @@ public static async Task BulkMergeAsync(this DbRepositoryThe number of rows affected by the execution. public static async Task BulkMergeAsync(this DbRepository repository, DbDataReader reader, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -447,13 +447,13 @@ public static async Task BulkMergeAsync(this DbRepository BulkMergeAsync(this DbRepository repository, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { // Create a connection @@ -492,15 +492,15 @@ public static async Task BulkMergeAsync(this DbRepository re /// The number of rows affected by the execution. public static async Task BulkMergeAsync(this DbRepository repository, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -542,15 +542,15 @@ public static async Task BulkMergeAsync(this DbRepository BulkMergeAsync(this DbRepository repository, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { // Create a connection diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/DbRepository/BulkUpdate.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/DbRepository/BulkUpdate.cs index 51facc2ae..0394830f1 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/DbRepository/BulkUpdate.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/DbRepository/BulkUpdate.cs @@ -1,11 +1,11 @@ -using Microsoft.Data.SqlClient; -using System; +using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using Microsoft.Data.SqlClient; namespace RepoDb { @@ -32,13 +32,13 @@ public static partial class DbRepositoryExtension /// The number of rows affected by the execution. public static int BulkUpdate(this DbRepository repository, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { // Create a connection @@ -74,13 +74,13 @@ public static int BulkUpdate(this DbRepository repositor public static int BulkUpdate(this DbRepository repository, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { // Create a connection @@ -115,13 +115,13 @@ public static int BulkUpdate(this DbRepository repositor /// The number of rows affected by the execution. public static int BulkUpdate(this DbRepository repository, DbDataReader reader, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { // Create a connection @@ -160,13 +160,13 @@ public static int BulkUpdate(this DbRepository repositor public static int BulkUpdate(this DbRepository repository, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) { // Create a connection using var bulkDbConnector = new BulkDbConnector(transaction, repository); @@ -201,14 +201,14 @@ public static int BulkUpdate(this DbRepository repository, /// The number of rows affected by the execution. public static int BulkUpdate(this DbRepository repository, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { // Create a connection @@ -245,14 +245,14 @@ public static int BulkUpdate(this DbRepository repositor public static int BulkUpdate(this DbRepository repository, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) { // Create a connection using var bulkDbConnector = new BulkDbConnector(transaction, repository); @@ -292,13 +292,13 @@ public static int BulkUpdate(this DbRepository repository, /// The number of rows affected by the execution. public static async Task BulkUpdateAsync(this DbRepository repository, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -337,13 +337,13 @@ public static async Task BulkUpdateAsync(this DbRepository BulkUpdateAsync(this DbRepository repository, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -381,13 +381,13 @@ public static async Task BulkUpdateAsync(this DbRepositoryThe number of rows affected by the execution. public static async Task BulkUpdateAsync(this DbRepository repository, DbDataReader reader, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -429,13 +429,13 @@ public static async Task BulkUpdateAsync(this DbRepository BulkUpdateAsync(this DbRepository repository, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { // Create a connection @@ -473,14 +473,14 @@ public static async Task BulkUpdateAsync(this DbRepository r /// The number of rows affected by the execution. public static async Task BulkUpdateAsync(this DbRepository repository, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -520,14 +520,14 @@ public static async Task BulkUpdateAsync(this DbRepository BulkUpdateAsync(this DbRepository repository, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { // Create a connection diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/SqlConnection/BulkDelete.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/SqlConnection/BulkDelete.cs index c5cb39169..b2c98a2fc 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/SqlConnection/BulkDelete.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/SqlConnection/BulkDelete.cs @@ -1,11 +1,12 @@ -using Microsoft.Data.SqlClient; -using System; +using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using Microsoft.Data.SqlClient; +using RepoDb.Interfaces; namespace RepoDb { @@ -30,11 +31,11 @@ public static partial class SqlConnectionExtension /// The number of rows affected by the execution. public static int BulkDelete(this SqlConnection connection, IEnumerable primaryKeys, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { return BulkDeleteInternal(connection: connection, @@ -64,14 +65,14 @@ public static int BulkDelete(this SqlConnection connection, /// The number of rows affected by the execution. public static int BulkDelete(this SqlConnection connection, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { using var reader = new DataEntityDataReader(entities); @@ -108,14 +109,14 @@ public static int BulkDelete(this SqlConnection connection, public static int BulkDelete(this SqlConnection connection, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { using var reader = new DataEntityDataReader(entities); @@ -150,14 +151,14 @@ public static int BulkDelete(this SqlConnection connection, /// The number of rows affected by the execution. public static int BulkDelete(this SqlConnection connection, DbDataReader reader, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { return BulkDeleteInternal(connection: connection, @@ -191,15 +192,15 @@ public static int BulkDelete(this SqlConnection connection, /// The number of rows affected by the execution. public static int BulkDelete(this SqlConnection connection, DataTable dataTable, - Expression> qualifiers = null, + Expression>? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { return BulkDeleteInternal(connection: connection, @@ -235,11 +236,11 @@ public static int BulkDelete(this SqlConnection connection, public static int BulkDelete(this SqlConnection connection, string tableName, IEnumerable primaryKeys, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) { return BulkDeleteInternal(connection: connection, tableName: tableName, @@ -269,14 +270,14 @@ public static int BulkDelete(this SqlConnection connection, public static int BulkDelete(this SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) { return BulkDeleteInternal(connection: connection, tableName: tableName, @@ -310,15 +311,15 @@ public static int BulkDelete(this SqlConnection connection, public static int BulkDelete(this SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) { return BulkDeleteInternal(connection: connection, tableName: tableName, @@ -353,11 +354,11 @@ public static int BulkDelete(this SqlConnection connection, /// The number of rows affected by the execution. public static Task BulkDeleteAsync(this SqlConnection connection, IEnumerable primaryKeys, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -390,14 +391,14 @@ public static Task BulkDeleteAsync(this SqlConnection connection, /// The number of rows affected by the execution. public static async Task BulkDeleteAsync(this SqlConnection connection, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -437,14 +438,14 @@ public static async Task BulkDeleteAsync(this SqlConnection connec public static async Task BulkDeleteAsync(this SqlConnection connection, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -482,14 +483,14 @@ public static async Task BulkDeleteAsync(this SqlConnection connec /// The number of rows affected by the execution. public static Task BulkDeleteAsync(this SqlConnection connection, DbDataReader reader, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -526,15 +527,15 @@ public static Task BulkDeleteAsync(this SqlConnection connection, /// The number of rows affected by the execution. public static Task BulkDeleteAsync(this SqlConnection connection, DataTable dataTable, - Expression> qualifiers = null, + Expression>? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -573,11 +574,11 @@ public static Task BulkDeleteAsync(this SqlConnection connection, public static Task BulkDeleteAsync(this SqlConnection connection, string tableName, IEnumerable primaryKeys, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { return BulkDeleteAsyncInternal(connection: connection, @@ -610,14 +611,14 @@ public static Task BulkDeleteAsync(this SqlConnection connection, public static Task BulkDeleteAsync(this SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { return BulkDeleteAsyncInternal(connection: connection, @@ -654,15 +655,15 @@ public static Task BulkDeleteAsync(this SqlConnection connection, public static Task BulkDeleteAsync(this SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { return BulkDeleteAsyncInternal(connection: connection, @@ -699,11 +700,11 @@ public static Task BulkDeleteAsync(this SqlConnection connection, internal static int BulkDeleteInternal(SqlConnection connection, string tableName, IEnumerable primaryKeys, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) => + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) => BulkDeleteInternalBase(connection, tableName, primaryKeys, @@ -731,20 +732,20 @@ internal static int BulkDeleteInternal(SqlConnection connection, internal static int BulkDeleteInternal(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) => + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) => BulkDeleteInternalBase(connection, tableName, reader, qualifiers, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, @@ -770,22 +771,22 @@ internal static int BulkDeleteInternal(SqlConnection connection, internal static int BulkDeleteInternal(SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) => + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) => BulkDeleteInternalBase(connection, tableName, dataTable, qualifiers, rowState, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, @@ -807,16 +808,18 @@ internal static int BulkDeleteInternal(SqlConnection connection, /// /// /// + /// /// /// internal static Task BulkDeleteAsyncInternal(SqlConnection connection, string tableName, IEnumerable primaryKeys, - string hints = null, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) => BulkDeleteAsyncInternalBase(connection, tableName, @@ -826,6 +829,7 @@ internal static Task BulkDeleteAsyncInternal(SqlConnection connection, batchSize, usePhysicalPseudoTempTable, transaction, + trace, cancellationToken); /// @@ -842,31 +846,34 @@ internal static Task BulkDeleteAsyncInternal(SqlConnection connection, /// /// /// + /// /// /// internal static Task BulkDeleteAsyncInternal(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) => BulkDeleteAsyncInternalBase(connection, tableName, reader, qualifiers, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, usePhysicalPseudoTempTable, transaction, + trace, cancellationToken); /// @@ -884,20 +891,22 @@ internal static Task BulkDeleteAsyncInternal(SqlConnection connection, /// /// /// + /// /// /// internal static Task BulkDeleteAsyncInternal(SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) => BulkDeleteAsyncInternalBase(connection, tableName, @@ -905,12 +914,13 @@ internal static Task BulkDeleteAsyncInternal(SqlConnection connection, qualifiers, rowState, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, usePhysicalPseudoTempTable, transaction, + trace, cancellationToken); #endregion diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/SqlConnection/BulkInsert.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/SqlConnection/BulkInsert.cs index 13dd78d0e..04a0a02d8 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/SqlConnection/BulkInsert.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/SqlConnection/BulkInsert.cs @@ -1,10 +1,11 @@ -using Microsoft.Data.SqlClient; -using System.Collections.Generic; +using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq; using System.Threading; using System.Threading.Tasks; +using Microsoft.Data.SqlClient; +using RepoDb.Interfaces; namespace RepoDb { @@ -32,14 +33,14 @@ public static partial class SqlConnectionExtension /// The number of rows affected by the execution. public static int BulkInsert(this SqlConnection connection, IEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { return BulkInsertInternal(connection: connection, @@ -74,14 +75,14 @@ public static int BulkInsert(this SqlConnection connection, public static int BulkInsert(this SqlConnection connection, string tableName, IEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { return BulkInsertInternal(connection: connection, @@ -111,11 +112,11 @@ public static int BulkInsert(this SqlConnection connection, /// The number of rows affected by the execution. public static int BulkInsert(this SqlConnection connection, DbDataReader reader, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, int? bulkCopyTimeout = null, int? batchSize = null, - SqlTransaction transaction = null) + SqlTransaction? transaction = null) where TEntity : class { return BulkInsertInternal(connection: connection, @@ -147,11 +148,11 @@ public static int BulkInsert(this SqlConnection connection, public static int BulkInsert(this SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, int? bulkCopyTimeout = null, int? batchSize = null, - SqlTransaction transaction = null) + SqlTransaction? transaction = null) { return BulkInsertInternal(connection: connection, tableName: tableName, @@ -182,14 +183,14 @@ public static int BulkInsert(this SqlConnection connection, public static int BulkInsert(this SqlConnection connection, DataTable dataTable, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { return BulkInsertInternal(connection: connection, @@ -226,14 +227,14 @@ public static int BulkInsert(this SqlConnection connection, string tableName, DataTable dataTable, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) { return BulkInsertInternal(connection: connection, tableName: tableName, @@ -271,14 +272,14 @@ public static int BulkInsert(this SqlConnection connection, /// The number of rows affected by the execution. public static Task BulkInsertAsync(this SqlConnection connection, IEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -316,14 +317,14 @@ public static Task BulkInsertAsync(this SqlConnection connection, public static Task BulkInsertAsync(this SqlConnection connection, string tableName, IEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -356,11 +357,11 @@ public static Task BulkInsertAsync(this SqlConnection connection, /// The number of rows affected by the execution. public static async Task BulkInsertAsync(this SqlConnection connection, DbDataReader reader, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, int? bulkCopyTimeout = null, int? batchSize = null, - SqlTransaction transaction = null, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -374,7 +375,7 @@ public static async Task BulkInsertAsync(this SqlConnection connec transaction: transaction, cancellationToken: cancellationToken); } - + /// /// Bulk insert a list of data entity objects into the database in an asynchronous way. /// @@ -393,14 +394,14 @@ public static async Task BulkInsertAsync(this SqlConnection connec /// The number of rows affected by the execution. public static Task BulkInsertAsync(this SqlConnection connection, IAsyncEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -438,14 +439,14 @@ public static Task BulkInsertAsync(this SqlConnection connection, public static Task BulkInsertAsync(this SqlConnection connection, string tableName, IAsyncEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -483,11 +484,11 @@ public static Task BulkInsertAsync(this SqlConnection connection, public static Task BulkInsertAsync(this SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, int? bulkCopyTimeout = null, int? batchSize = null, - SqlTransaction transaction = null, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { return BulkInsertAsyncInternal(connection: connection, @@ -521,14 +522,14 @@ public static Task BulkInsertAsync(this SqlConnection connection, public static Task BulkInsertAsync(this SqlConnection connection, DataTable dataTable, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -568,14 +569,14 @@ public static Task BulkInsertAsync(this SqlConnection connection, string tableName, DataTable dataTable, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { return BulkInsertAsyncInternal(connection: connection, @@ -616,20 +617,20 @@ public static Task BulkInsertAsync(this SqlConnection connection, internal static int BulkInsertInternal(SqlConnection connection, string tableName, IEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class => BulkInsertInternalBase(connection, tableName, entities, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, @@ -652,16 +653,16 @@ internal static int BulkInsertInternal(SqlConnection connection, internal static int BulkInsertInternal(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, int? bulkCopyTimeout = null, int? batchSize = null, - SqlTransaction transaction = null) => + SqlTransaction? transaction = null) => BulkInsertInternalBase(connection, tableName, reader, mappings, - options.GetValueOrDefault(), + options, bulkCopyTimeout, batchSize, transaction); @@ -686,20 +687,20 @@ internal static int BulkInsertInternal(SqlConnection connection, string tableName, DataTable dataTable, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) => + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) => BulkInsertInternalBase(connection, tableName, dataTable, rowState, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, @@ -726,32 +727,35 @@ internal static int BulkInsertInternal(SqlConnection connection, /// /// /// + /// /// /// internal static Task BulkInsertAsyncInternal(SqlConnection connection, string tableName, IEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) where TEntity : class => BulkInsertAsyncInternalBase(connection, tableName, entities, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, isReturnIdentity, usePhysicalPseudoTempTable, transaction, + trace, cancellationToken); /// @@ -770,17 +774,17 @@ internal static Task BulkInsertAsyncInternal(SqlConnection connect internal static Task BulkInsertAsyncInternal(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, int? bulkCopyTimeout = null, int? batchSize = null, - SqlTransaction transaction = null, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) => BulkInsertAsyncInternalBase(connection, tableName, reader, mappings, - options.GetValueOrDefault(), + options, bulkCopyTimeout, batchSize, transaction, @@ -801,35 +805,38 @@ internal static Task BulkInsertAsyncInternal(SqlConnection connection, /// The flags that signify whether the identity values will be returned. /// The flags that signify whether to create a physical pseudo table. This argument will only be used if the 'isReturnIdentity' argument is 'true'. /// The transaction to be used. + /// /// The object to be used during the asynchronous operation. /// The number of rows affected by the execution. internal static Task BulkInsertAsyncInternal(SqlConnection connection, string tableName, DataTable dataTable, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) => BulkInsertAsyncInternalBase(connection, tableName, dataTable, rowState, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, isReturnIdentity, usePhysicalPseudoTempTable, transaction, + trace, cancellationToken); - + /// /// /// @@ -845,35 +852,38 @@ internal static Task BulkInsertAsyncInternal(SqlConnection connection, /// /// /// + /// /// /// internal static async Task BulkInsertAsyncInternal(SqlConnection connection, string tableName, IAsyncEnumerable entities, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) where TEntity : class { var loadedEntities = await entities.ToListAsync(cancellationToken); - + return await BulkInsertAsyncInternalBase(connection, tableName, loadedEntities, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, isReturnIdentity, usePhysicalPseudoTempTable, transaction, + trace, cancellationToken); } diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/SqlConnection/BulkMerge.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/SqlConnection/BulkMerge.cs index 35c0e995f..7ebe199ed 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/SqlConnection/BulkMerge.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/SqlConnection/BulkMerge.cs @@ -1,11 +1,12 @@ -using Microsoft.Data.SqlClient; -using System; +using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using Microsoft.Data.SqlClient; +using RepoDb.Interfaces; namespace RepoDb { @@ -31,18 +32,20 @@ public static partial class SqlConnectionExtension /// The flags that signify whether the identity values will be returned. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// /// The number of rows affected by the execution. public static int BulkMerge(this SqlConnection connection, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null) where TEntity : class { return BulkMergeInternal(connection: connection, @@ -56,7 +59,8 @@ public static int BulkMerge(this SqlConnection connection, batchSize: batchSize, isReturnIdentity: isReturnIdentity, usePhysicalPseudoTempTable: usePhysicalPseudoTempTable, - transaction: transaction); + transaction: transaction, + trace: trace); } /// @@ -75,19 +79,21 @@ public static int BulkMerge(this SqlConnection connection, /// The flags that signify whether the identity values will be returned. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// /// The number of rows affected by the execution. public static int BulkMerge(this SqlConnection connection, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace trace = null) where TEntity : class { return BulkMergeInternal(connection: connection, @@ -101,7 +107,8 @@ public static int BulkMerge(this SqlConnection connection, batchSize: batchSize, isReturnIdentity: isReturnIdentity, usePhysicalPseudoTempTable: usePhysicalPseudoTempTable, - transaction: transaction); + transaction: transaction, + trace: trace); } /// @@ -118,17 +125,19 @@ public static int BulkMerge(this SqlConnection connection, /// The size per batch to be used. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// /// The number of rows affected by the execution. public static int BulkMerge(this SqlConnection connection, DbDataReader reader, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace trace = null) where TEntity : class { return BulkMergeInternal(connection: connection, @@ -141,7 +150,8 @@ public static int BulkMerge(this SqlConnection connection, bulkCopyTimeout: bulkCopyTimeout, batchSize: batchSize, usePhysicalPseudoTempTable: usePhysicalPseudoTempTable, - transaction: transaction); + transaction: transaction, + trace: trace); } #endregion @@ -162,18 +172,20 @@ public static int BulkMerge(this SqlConnection connection, /// The size per batch to be used. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// /// The number of rows affected by the execution. public static int BulkMerge(this SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null) { return BulkMergeInternal(connection: connection, tableName: tableName, @@ -185,7 +197,8 @@ public static int BulkMerge(this SqlConnection connection, bulkCopyTimeout: bulkCopyTimeout, batchSize: batchSize, usePhysicalPseudoTempTable: usePhysicalPseudoTempTable, - transaction: transaction); + transaction: transaction, + trace: trace); } /// @@ -204,19 +217,21 @@ public static int BulkMerge(this SqlConnection connection, /// The flags that signify whether the identity values will be returned. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// /// The number of rows affected by the execution. public static int BulkMerge(this SqlConnection connection, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null) where TEntity : class { return BulkMergeInternal(connection: connection, @@ -231,7 +246,8 @@ public static int BulkMerge(this SqlConnection connection, batchSize: batchSize, isReturnIdentity: isReturnIdentity, usePhysicalPseudoTempTable: usePhysicalPseudoTempTable, - transaction: transaction); + transaction: transaction, + trace: trace); } /// @@ -254,16 +270,16 @@ public static int BulkMerge(this SqlConnection connection, public static int BulkMerge(this SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) { return BulkMergeInternal(connection: connection, tableName: tableName, @@ -299,19 +315,21 @@ public static int BulkMerge(this SqlConnection connection, /// The flags that signify whether the identity values will be returned. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// /// The object to be used during the asynchronous operation. /// The number of rows affected by the execution. public static Task BulkMergeAsync(this SqlConnection connection, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -327,6 +345,7 @@ public static Task BulkMergeAsync(this SqlConnection connection, isReturnIdentity: isReturnIdentity, usePhysicalPseudoTempTable: usePhysicalPseudoTempTable, transaction: transaction, + trace: trace, cancellationToken: cancellationToken); } @@ -346,20 +365,22 @@ public static Task BulkMergeAsync(this SqlConnection connection, /// The flags that signify whether the identity values will be returned. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// The tracer to be used. /// The object to be used during the asynchronous operation. /// The number of rows affected by the execution. public static Task BulkMergeAsync(this SqlConnection connection, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -375,6 +396,7 @@ public static Task BulkMergeAsync(this SqlConnection connection, isReturnIdentity: isReturnIdentity, usePhysicalPseudoTempTable: usePhysicalPseudoTempTable, transaction: transaction, + trace: trace, cancellationToken: cancellationToken); } @@ -392,18 +414,20 @@ public static Task BulkMergeAsync(this SqlConnection connection, /// The size per batch to be used. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// /// The object to be used during the asynchronous operation. /// The number of rows affected by the execution. public static Task BulkMergeAsync(this SqlConnection connection, DbDataReader reader, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -418,6 +442,7 @@ public static Task BulkMergeAsync(this SqlConnection connection, batchSize: batchSize, usePhysicalPseudoTempTable: usePhysicalPseudoTempTable, transaction: transaction, + trace: trace, cancellationToken: cancellationToken); } @@ -439,19 +464,21 @@ public static Task BulkMergeAsync(this SqlConnection connection, /// The size per batch to be used. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// /// The object to be used during the asynchronous operation. /// The number of rows affected by the execution. public static Task BulkMergeAsync(this SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) { return BulkMergeAsyncInternal(connection: connection, @@ -465,6 +492,7 @@ public static Task BulkMergeAsync(this SqlConnection connection, batchSize: batchSize, usePhysicalPseudoTempTable: usePhysicalPseudoTempTable, transaction: transaction, + trace: trace, cancellationToken: cancellationToken); } @@ -484,20 +512,22 @@ public static Task BulkMergeAsync(this SqlConnection connection, /// The flags that signify whether the identity values will be returned. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// /// The object to be used during the asynchronous operation. /// The number of rows affected by the execution. public static Task BulkMergeAsync(this SqlConnection connection, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -533,21 +563,23 @@ public static Task BulkMergeAsync(this SqlConnection connection, /// The flags that signify whether the identity values will be returned. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// /// The object to be used during the asynchronous operation. /// The number of rows affected by the execution. public static Task BulkMergeAsync(this SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) { return BulkMergeAsyncInternal(connection: connection, @@ -563,6 +595,7 @@ public static Task BulkMergeAsync(this SqlConnection connection, isReturnIdentity: isReturnIdentity, usePhysicalPseudoTempTable: usePhysicalPseudoTempTable, transaction: transaction, + trace: trace, cancellationToken: cancellationToken); } @@ -586,32 +619,35 @@ public static Task BulkMergeAsync(this SqlConnection connection, /// /// /// + /// /// internal static int BulkMergeInternal(SqlConnection connection, string tableName, IEnumerable entities, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null) where TEntity : class => BulkMergeInternalBase(connection, tableName, entities, qualifiers, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, isReturnIdentity, usePhysicalPseudoTempTable, - transaction); + transaction, + trace); /// /// Bulk merge an instance of object into the database. @@ -627,29 +663,32 @@ internal static int BulkMergeInternal(SqlConnection connection, /// The size per batch to be used. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// /// The number of rows affected by the execution. internal static int BulkMergeInternal(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) => + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null) => BulkMergeInternalBase(connection, tableName, reader, qualifiers, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, usePhysicalPseudoTempTable, - transaction); + transaction, + trace); /// /// Bulk merge an instance of object into the database. @@ -667,33 +706,36 @@ internal static int BulkMergeInternal(SqlConnection connection, /// The flags that signify whether the identity values will be returned. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// /// The number of rows affected by the execution. internal static int BulkMergeInternal(SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) => + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null) => BulkMergeInternalBase(connection, tableName, dataTable, qualifiers, rowState, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, isReturnIdentity, usePhysicalPseudoTempTable, - transaction); + transaction, + trace); #endregion @@ -715,20 +757,22 @@ internal static int BulkMergeInternal(SqlConnection connection, /// /// /// + /// /// /// internal static Task BulkMergeAsyncInternal(SqlConnection connection, string tableName, IEnumerable entities, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) where TEntity : class => BulkMergeAsyncInternalBase(connection, @@ -736,13 +780,14 @@ internal static Task BulkMergeAsyncInternal(SqlConnection connecti entities, qualifiers, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, isReturnIdentity, usePhysicalPseudoTempTable, transaction, + trace, cancellationToken); /// @@ -759,31 +804,34 @@ internal static Task BulkMergeAsyncInternal(SqlConnection connecti /// The size per batch to be used. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// /// The object to be used during the asynchronous operation. /// The number of rows affected by the execution. internal static Task BulkMergeAsyncInternal(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) => BulkMergeAsyncInternalBase(connection, tableName, reader, qualifiers, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, usePhysicalPseudoTempTable, transaction, + trace, cancellationToken); /// @@ -802,21 +850,23 @@ internal static Task BulkMergeAsyncInternal(SqlConnection connection, /// The flags that signify whether the identity values will be returned. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// /// The object to be used during the asynchronous operation. /// The number of rows affected by the execution. internal static Task BulkMergeAsyncInternal(SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? isReturnIdentity = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool isReturnIdentity = false, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) => BulkMergeAsyncInternalBase(connection, tableName, @@ -824,13 +874,14 @@ internal static Task BulkMergeAsyncInternal(SqlConnection connection, qualifiers, rowState, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, isReturnIdentity, usePhysicalPseudoTempTable, transaction, + trace, cancellationToken); #endregion diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/SqlConnection/BulkUpdate.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/SqlConnection/BulkUpdate.cs index d510f8684..e5dc98e14 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/SqlConnection/BulkUpdate.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/Microsoft.Data.SqlClient/SqlConnection/BulkUpdate.cs @@ -1,11 +1,12 @@ -using Microsoft.Data.SqlClient; -using System; +using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; +using Microsoft.Data.SqlClient; +using RepoDb.Interfaces; namespace RepoDb { @@ -33,14 +34,14 @@ public static partial class SqlConnectionExtension /// The number of rows affected by the execution. public static int BulkUpdate(this SqlConnection connection, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { using var reader = new DataEntityDataReader(entities); @@ -77,14 +78,14 @@ public static int BulkUpdate(this SqlConnection connection, public static int BulkUpdate(this SqlConnection connection, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { using var reader = new DataEntityDataReader(entities); @@ -119,14 +120,14 @@ public static int BulkUpdate(this SqlConnection connection, /// The number of rows affected by the execution. public static int BulkUpdate(this SqlConnection connection, DbDataReader reader, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { return BulkUpdateInternal(connection: connection, @@ -164,14 +165,14 @@ public static int BulkUpdate(this SqlConnection connection, public static int BulkUpdate(this SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) { return BulkUpdateInternal(connection: connection, tableName: tableName, @@ -204,15 +205,15 @@ public static int BulkUpdate(this SqlConnection connection, /// The number of rows affected by the execution. public static int BulkUpdate(this SqlConnection connection, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) where TEntity : class { return BulkUpdateInternal(connection: connection, @@ -248,15 +249,15 @@ public static int BulkUpdate(this SqlConnection connection, public static int BulkUpdate(this SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) { return BulkUpdateInternal(connection: connection, tableName: tableName, @@ -294,14 +295,14 @@ public static int BulkUpdate(this SqlConnection connection, /// The number of rows affected by the execution. public static async Task BulkUpdateAsync(this SqlConnection connection, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -341,14 +342,14 @@ public static async Task BulkUpdateAsync(this SqlConnection connec public static async Task BulkUpdateAsync(this SqlConnection connection, string tableName, IEnumerable entities, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -386,14 +387,14 @@ public static async Task BulkUpdateAsync(this SqlConnection connec /// The number of rows affected by the execution. public static Task BulkUpdateAsync(this SqlConnection connection, DbDataReader reader, - Expression> qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + Expression>? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -434,14 +435,14 @@ public static Task BulkUpdateAsync(this SqlConnection connection, public static Task BulkUpdateAsync(this SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { return BulkUpdateAsyncInternal(connection: connection, @@ -477,15 +478,15 @@ public static Task BulkUpdateAsync(this SqlConnection connection, /// The number of rows affected by the execution. public static Task BulkUpdateAsync(this SqlConnection connection, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) where TEntity : class { @@ -524,15 +525,15 @@ public static Task BulkUpdateAsync(this SqlConnection connection, public static Task BulkUpdateAsync(this SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, CancellationToken cancellationToken = default) { return BulkUpdateAsyncInternal(connection: connection, @@ -572,20 +573,20 @@ public static Task BulkUpdateAsync(this SqlConnection connection, internal static int BulkUpdateInternal(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) => + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) => BulkUpdateInternalBase(connection, tableName, reader, qualifiers, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, @@ -611,22 +612,22 @@ internal static int BulkUpdateInternal(SqlConnection connection, internal static int BulkUpdateInternal(SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null) => + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null) => BulkUpdateInternalBase(connection, tableName, dataTable, qualifiers, rowState, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, @@ -651,31 +652,34 @@ internal static int BulkUpdateInternal(SqlConnection connection, /// The size per batch to be used. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// /// The object to be used during the asynchronous operation. /// The number of rows affected by the execution. internal static Task BulkUpdateAsyncInternal(SqlConnection connection, string tableName, DbDataReader reader, - IEnumerable qualifiers = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? qualifiers = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) => BulkUpdateAsyncInternalBase(connection, tableName, reader, qualifiers, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, usePhysicalPseudoTempTable, transaction, + trace, cancellationToken); /// @@ -693,20 +697,22 @@ internal static Task BulkUpdateAsyncInternal(SqlConnection connection, /// The size per batch to be used. /// The flags that signify whether to create a physical pseudo table. /// The transaction to be used. + /// /// The object to be used during the asynchronous operation. /// The number of rows affected by the execution. internal static Task BulkUpdateAsyncInternal(SqlConnection connection, string tableName, DataTable dataTable, - IEnumerable qualifiers = null, + IEnumerable? qualifiers = null, DataRowState? rowState = null, - IEnumerable mappings = null, - SqlBulkCopyOptions? options = null, - string hints = null, + IEnumerable? mappings = null, + SqlBulkCopyOptions options = default, + string? hints = null, int? bulkCopyTimeout = null, int? batchSize = null, - bool? usePhysicalPseudoTempTable = null, - SqlTransaction transaction = null, + bool usePhysicalPseudoTempTable = false, + SqlTransaction? transaction = null, + ITrace? trace = null, CancellationToken cancellationToken = default) => BulkUpdateAsyncInternalBase(connection, tableName, @@ -714,12 +720,13 @@ internal static Task BulkUpdateAsyncInternal(SqlConnection connection, qualifiers, rowState, mappings, - options.GetValueOrDefault(), + options, hints, bulkCopyTimeout, batchSize, usePhysicalPseudoTempTable, transaction, + trace, cancellationToken); #endregion diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations.csproj b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations.csproj index 7004d1141..15b5e96db 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations.csproj +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations.csproj @@ -1,49 +1,30 @@  - - - RepoDb.SqlServer.BulkOperations - netstandard2.0;net6.0;net7.0;net8.0 - 0.0.1 - 0.0.1 - 0.0.1 - true - An extension library that contains the official Bulk Operations of RepoDb for SQL Server. - orm hybrid-orm micro-orm sqlserver bulkoperations - https://github.com/mikependon/RepoDb/tree/master/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations - http://repodb.net/release/sqlserverbulk - true - - - - - - - - - - - - - - - - - - - - - True - - - - - - - - - - - - - + + RepoDb.SqlServer.BulkOperations + netstandard2.0;net6.0;net7.0;net8.0 + annotations + An extension library that contains the official Bulk Operations of RepoDb for SQL Server. + orm hybrid-orm micro-orm sqlserver bulkoperations + https://github.com/mikependon/RepoDb/tree/master/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations + http://repodb.net/release/sqlserverbulk + + + + + + + + + + + + + + + + + + + + diff --git a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/SqlConnectionExtension.cs b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/SqlConnectionExtension.cs index f8bb93efc..ede295f1d 100644 --- a/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/SqlConnectionExtension.cs +++ b/RepoDb.Extensions/RepoDb.SqlServer.BulkOperations/RepoDb.SqlServer.BulkOperations/SqlConnectionExtension.cs @@ -1,8 +1,4 @@ -using RepoDb.Exceptions; -using RepoDb.Extensions; -using RepoDb.Interfaces; -using RepoDb.SqlServer.BulkOperations; -using System; +using System; using System.Collections.Generic; using System.Data; using System.Data.Common; @@ -12,6 +8,10 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Data.SqlClient; +using RepoDb.Exceptions; +using RepoDb.Extensions; +using RepoDb.Interfaces; +using RepoDb.SqlServer.BulkOperations; namespace RepoDb { @@ -606,6 +606,7 @@ private static string GetBulkDeleteSqlText(string tableName, /// /// /// + /// /// private static string GetBulkInsertSqlText(string tableName, string tempTableName, @@ -614,7 +615,7 @@ private static string GetBulkInsertSqlText(string tableName, string hints, IDbSetting dbSetting, bool isReturnIdentity, - bool keepIdentity) + bool forceIdentityColumn) { // Validate the presence if (fields?.Any() != true) @@ -627,13 +628,13 @@ private static string GetBulkInsertSqlText(string tableName, // Insertable fields var insertableFields = fields - .Where(field => keepIdentity == true || string.Equals(field.Name, identityField?.Name, StringComparison.OrdinalIgnoreCase) == false); + .Where(field => forceIdentityColumn == true || string.Equals(field.Name, identityField?.Name, StringComparison.OrdinalIgnoreCase) == false); // Compose the statement builder.Clear(); // SET IDENTITY_INSERT ON - if (keepIdentity) + if (forceIdentityColumn) { builder .WriteText("SET IDENTITY_INSERT") @@ -703,7 +704,7 @@ private static string GetBulkInsertSqlText(string tableName, builder.End(); // SET IDENTITY_INSERT OFF (probably not necessary, but it won't hurt) - if (keepIdentity) + if (forceIdentityColumn) { builder .WriteText("SET IDENTITY_INSERT") @@ -727,7 +728,7 @@ private static string GetBulkInsertSqlText(string tableName, /// /// /// - /// + /// /// private static string GetBulkMergeSqlText(string tableName, string tempTableName, @@ -738,7 +739,7 @@ private static string GetBulkMergeSqlText(string tableName, string hints, IDbSetting dbSetting, bool isReturnIdentity, - bool keepIdentity) + bool forceIdentityColumn) { // Validate the presence if (fields?.Any() != true) @@ -756,7 +757,7 @@ private static string GetBulkMergeSqlText(string tableName, // Insertable fields var insertableFields = fields - .Where(field => keepIdentity == true || string.Equals(field.Name, identityField?.Name, StringComparison.OrdinalIgnoreCase) == false); + .Where(field => forceIdentityColumn == true || string.Equals(field.Name, identityField?.Name, StringComparison.OrdinalIgnoreCase) == false); // Updatable fields var updateableFields = fields @@ -769,7 +770,7 @@ private static string GetBulkMergeSqlText(string tableName, builder.Clear(); // SET IDENTITY_INSERT ON - if (keepIdentity) + if (forceIdentityColumn) { builder .WriteText("SET IDENTITY_INSERT") @@ -859,7 +860,7 @@ private static string GetBulkMergeSqlText(string tableName, builder.End(); // SET IDENTITY_INSERT OFF (probably not necessary, but it won't hurt) - if (keepIdentity) + if (forceIdentityColumn) { builder .WriteText("SET IDENTITY_INSERT") diff --git a/RepoDb.MySql/RepoDb.MySql.IntegrationTests/DbHelperTests.cs b/RepoDb.MySql/RepoDb.MySql.IntegrationTests/DbHelperTests.cs index 90f6c6ddc..9e4651e5f 100644 --- a/RepoDb.MySql/RepoDb.MySql.IntegrationTests/DbHelperTests.cs +++ b/RepoDb.MySql/RepoDb.MySql.IntegrationTests/DbHelperTests.cs @@ -43,8 +43,9 @@ public void TestDbHelperGetFields() using (var reader = connection.ExecuteReader(@"SELECT COLUMN_NAME AS ColumnName FROM INFORMATION_SCHEMA.COLUMNS WHERE - TABLE_NAME = @TableName - ORDER BY ORDINAL_POSITION;", new { TableName = "CompleteTable" })) + TABLE_NAME = @TableName + AND TABLE_SCHEMA = @TableSchema + ORDER BY ORDINAL_POSITION;", new { TableName = "CompleteTable", TableSchema = connection.Database })) { var fieldCount = 0; @@ -120,8 +121,9 @@ public async Task TestDbHelperGetFieldsAsync() using (var reader = connection.ExecuteReader(@"SELECT COLUMN_NAME AS ColumnName FROM INFORMATION_SCHEMA.COLUMNS WHERE - TABLE_NAME = @TableName - ORDER BY ORDINAL_POSITION;", new { TableName = "CompleteTable" })) + TABLE_NAME = @TableName + AND TABLE_SCHEMA = @TableSchema + ORDER BY ORDINAL_POSITION;", new { TableName = "CompleteTable", TableSchema = connection.Database })) { var fieldCount = 0; diff --git a/RepoDb.MySql/RepoDb.MySql.IntegrationTests/RepoDb.MySql.IntegrationTests.csproj b/RepoDb.MySql/RepoDb.MySql.IntegrationTests/RepoDb.MySql.IntegrationTests.csproj index 53ab57ba0..789415825 100644 --- a/RepoDb.MySql/RepoDb.MySql.IntegrationTests/RepoDb.MySql.IntegrationTests.csproj +++ b/RepoDb.MySql/RepoDb.MySql.IntegrationTests/RepoDb.MySql.IntegrationTests.csproj @@ -1,25 +1,21 @@ - net6.0;net7.0;net8.0 false + true + true + true - portable true - - - - - + + - - - + \ No newline at end of file diff --git a/RepoDb.MySql/RepoDb.MySql.IntegrationTests/Setup/Database.cs b/RepoDb.MySql/RepoDb.MySql.IntegrationTests/Setup/Database.cs index 11d54c872..d69709937 100644 --- a/RepoDb.MySql/RepoDb.MySql.IntegrationTests/Setup/Database.cs +++ b/RepoDb.MySql/RepoDb.MySql.IntegrationTests/Setup/Database.cs @@ -1,7 +1,8 @@ -using RepoDb.MySql.IntegrationTests.Models; -using MySql.Data.MySqlClient; -using System; +using System; using System.Collections.Generic; +using MySql.Data.MySqlClient; +using RepoDb.Exceptions; +using RepoDb.MySql.IntegrationTests.Models; namespace RepoDb.MySql.IntegrationTests.Setup { @@ -25,13 +26,18 @@ public static class Database public static void Initialize() { - // Get the connection string - var connectionStringForSys = Environment.GetEnvironmentVariable("REPODB_CONSTR_SYS", EnvironmentVariableTarget.Process); - var connectionString = Environment.GetEnvironmentVariable("REPODB_CONSTR", EnvironmentVariableTarget.Process); - // Set the connection string - ConnectionStringForSys = (connectionStringForSys ?? @"Server=localhost;Database=sys;Uid=user;Pwd=Password123;"); - ConnectionString = (connectionString ?? @"Server=localhost;Database=RepoDb;Uid=user;Pwd=Password123;"); + ConnectionStringForSys = + Environment.GetEnvironmentVariable("REPODB_MYSQL_CONSTR_SYS") + ?? Environment.GetEnvironmentVariable("REPODB_CONSTR_SYS") + // ?? @"Server=127.0.0.1;Port=43306;Database=sys;User ID=root;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" // Docker test configuration + ?? @"Server=localhost;Database=sys;Uid=user;Pwd=Password123;"; + + ConnectionString = + Environment.GetEnvironmentVariable("REPODB_MYSQL_CONSTR_REPODB") + ?? Environment.GetEnvironmentVariable("REPODB_CONSTR") + // ?? @"Server=127.0.0.1;Port=43306;Database=RepoDb;User ID=root;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" // Docker test configuration + ?? @"Server=localhost;Database=RepoDb;Uid=user;Pwd=Password123;"; // Initialize MySql GlobalConfiguration @@ -49,8 +55,15 @@ public static void Cleanup() { using (var connection = new MySqlConnection(ConnectionString)) { - connection.Truncate(); - connection.Truncate(); + try + { + connection.Truncate(); + connection.Truncate(); + } + catch (MissingFieldsException) + { + // Table does not exist + } } } @@ -90,7 +103,8 @@ private static void CreateDatabase() { using (var connection = new MySqlConnection(ConnectionStringForSys)) { - connection.ExecuteNonQuery(@"CREATE SCHEMA IF NOT EXISTS `RepoDb`;"); + connection.ExecuteNonQuery(@"CREATE DATABASE IF NOT EXISTS `RepoDb`;"); + connection.ExecuteNonQuery(@"GRANT ALL Privileges on RepoDb.* to 'root'@'%';"); } } @@ -108,7 +122,7 @@ private static void CreateCompleteTable() { using (var connection = new MySqlConnection(ConnectionString)) { - connection.ExecuteNonQuery(@"CREATE TABLE IF NOT EXISTS `completetable` + connection.ExecuteNonQuery(@"CREATE TABLE IF NOT EXISTS `CompleteTable` ( `Id` bigint(20) NOT NULL AUTO_INCREMENT, `ColumnVarchar` varchar(256) DEFAULT NULL, @@ -161,7 +175,7 @@ private static void CreateNonIdentityCompleteTable() { using (var connection = new MySqlConnection(ConnectionString)) { - connection.ExecuteNonQuery(@"CREATE TABLE IF NOT EXISTS `nonidentitycompletetable` + connection.ExecuteNonQuery(@"CREATE TABLE IF NOT EXISTS `NonIdentityCompleteTable` ( `Id` bigint(20) NOT NULL, `ColumnVarchar` varchar(256) DEFAULT NULL, diff --git a/RepoDb.MySql/RepoDb.MySql.IntegrationTests/TransactionTests.cs b/RepoDb.MySql/RepoDb.MySql.IntegrationTests/TransactionTests.cs index 16554c7b0..220f35861 100644 --- a/RepoDb.MySql/RepoDb.MySql.IntegrationTests/TransactionTests.cs +++ b/RepoDb.MySql/RepoDb.MySql.IntegrationTests/TransactionTests.cs @@ -1,12 +1,12 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Linq; +using System.Threading.Tasks; +using System.Transactions; +using Microsoft.VisualStudio.TestTools.UnitTesting; using MySql.Data.MySqlClient; using RepoDb.Enumerations; using RepoDb.MySql.IntegrationTests; using RepoDb.MySql.IntegrationTests.Models; using RepoDb.MySql.IntegrationTests.Setup; -using System.Linq; -using System.Threading.Tasks; -using System.Transactions; namespace RepoDb.MySqlConnector.IntegrationTests { @@ -1458,7 +1458,7 @@ public async Task TestTransactionForInsertAllAsync() // Setup var entities = Helper.CreateCompleteTables(10); - using (var transaction = new TransactionScope()) + using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { using (var connection = new MySqlConnection(Database.ConnectionString)) { @@ -1484,7 +1484,7 @@ public void TestTransactionScopeForMergeAll() // Setup var entities = Helper.CreateCompleteTables(10); - using (var transaction = new TransactionScope()) + using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { using (var connection = new MySqlConnection(Database.ConnectionString)) { @@ -1506,7 +1506,7 @@ public async Task TestTransactionScopeForMergeAllAsync() // Setup var entities = Helper.CreateCompleteTables(10); - using (var transaction = new TransactionScope()) + using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { using (var connection = new MySqlConnection(Database.ConnectionString)) { @@ -1532,7 +1532,7 @@ public void TestTransactionScopeForUpdateAll() // Setup var entities = Helper.CreateCompleteTables(10); - using (var transaction = new TransactionScope()) + using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { using (var connection = new MySqlConnection(Database.ConnectionString)) { @@ -1563,7 +1563,7 @@ public async Task TestTransactionScopeForUpdateAllAsync() // Setup var entities = Helper.CreateCompleteTables(10); - using (var transaction = new TransactionScope()) + using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { using (var connection = new MySqlConnection(Database.ConnectionString)) { diff --git a/RepoDb.MySql/RepoDb.MySql.UnitTests/RepoDb.MySql.UnitTests.csproj b/RepoDb.MySql/RepoDb.MySql.UnitTests/RepoDb.MySql.UnitTests.csproj index fefe2bd55..296b9af06 100644 --- a/RepoDb.MySql/RepoDb.MySql.UnitTests/RepoDb.MySql.UnitTests.csproj +++ b/RepoDb.MySql/RepoDb.MySql.UnitTests/RepoDb.MySql.UnitTests.csproj @@ -1,18 +1,16 @@ - net6.0;net7.0;net8.0 false + true + true + true - - - - + + - - - + \ No newline at end of file diff --git a/RepoDb.MySql/RepoDb.MySql.UnitTests/StatementBuilderTest.cs b/RepoDb.MySql/RepoDb.MySql.UnitTests/StatementBuilderTest.cs index 5b5f8ec13..a37d9ef0d 100644 --- a/RepoDb.MySql/RepoDb.MySql.UnitTests/StatementBuilderTest.cs +++ b/RepoDb.MySql/RepoDb.MySql.UnitTests/StatementBuilderTest.cs @@ -1,8 +1,8 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; using MySql.Data.MySqlClient; using RepoDb.Enumerations; using RepoDb.Exceptions; -using System; namespace RepoDb.MySql.UnitTests { @@ -309,16 +309,15 @@ public void TestMySqlStatementBuilderCreateInsertAll() 3, null, null); - var expected = "INSERT INTO `Table` ( `Id`, `Name`, `Address` ) VALUES ( @Id, @Name, @Address ) ; SELECT NULL AS `Result`, @__RepoDb_OrderColumn_0 AS `OrderColumn` ; " + - "INSERT INTO `Table` ( `Id`, `Name`, `Address` ) VALUES ( @Id_1, @Name_1, @Address_1 ) ; SELECT NULL AS `Result`, @__RepoDb_OrderColumn_1 AS `OrderColumn` ; " + - "INSERT INTO `Table` ( `Id`, `Name`, `Address` ) VALUES ( @Id_2, @Name_2, @Address_2 ) ; SELECT NULL AS `Result`, @__RepoDb_OrderColumn_2 AS `OrderColumn` ;"; + var expected = "INSERT INTO `Table` ( `Id`, `Name`, `Address` ) VALUES ROW ( @Id, @Name, @Address ) ," + + " ROW ( @Id_1, @Name_1, @Address_1 ) , ROW ( @Id_2, @Name_2, @Address_2 ) ; SELECT NULL AS `Result`;"; // Assert Assert.AreEqual(expected, query); } [TestMethod] - public void TestMySqlStatementBuilderCreateInserAlltWithPrimary() + public void TestMySqlStatementBuilderCreateInsertAllWithPrimary() { // Setup var builder = StatementBuilderMapper.Get(); @@ -329,9 +328,8 @@ public void TestMySqlStatementBuilderCreateInserAlltWithPrimary() 3, new DbField("Id", true, false, false, typeof(int), null, null, null, null, false), null); - var expected = "INSERT INTO `Table` ( `Id`, `Name`, `Address` ) VALUES ( @Id, @Name, @Address ) ; SELECT @Id AS `Result`, @__RepoDb_OrderColumn_0 AS `OrderColumn` ; " + - "INSERT INTO `Table` ( `Id`, `Name`, `Address` ) VALUES ( @Id_1, @Name_1, @Address_1 ) ; SELECT @Id_1 AS `Result`, @__RepoDb_OrderColumn_1 AS `OrderColumn` ; " + - "INSERT INTO `Table` ( `Id`, `Name`, `Address` ) VALUES ( @Id_2, @Name_2, @Address_2 ) ; SELECT @Id_2 AS `Result`, @__RepoDb_OrderColumn_2 AS `OrderColumn` ;"; + var expected = "INSERT INTO `Table` ( `Id`, `Name`, `Address` ) VALUES ROW ( @Id, @Name, @Address ) , ROW ( @Id_1, @Name_1, @Address_1 ) ," + + " ROW ( @Id_2, @Name_2, @Address_2 ) ; SELECT @Id AS `Result`;"; // Assert Assert.AreEqual(expected, query); @@ -349,9 +347,9 @@ public void TestMySqlStatementBuilderCreateInsertAllWithIdentity() 3, null, new DbField("Id", false, true, false, typeof(int), null, null, null, null, false)); - var expected = "INSERT INTO `Table` ( `Name`, `Address` ) VALUES ( @Name, @Address ) ; SELECT LAST_INSERT_ID() AS `Result`, @__RepoDb_OrderColumn_0 AS `OrderColumn` ; " + - "INSERT INTO `Table` ( `Name`, `Address` ) VALUES ( @Name_1, @Address_1 ) ; SELECT LAST_INSERT_ID() AS `Result`, @__RepoDb_OrderColumn_1 AS `OrderColumn` ; " + - "INSERT INTO `Table` ( `Name`, `Address` ) VALUES ( @Name_2, @Address_2 ) ; SELECT LAST_INSERT_ID() AS `Result`, @__RepoDb_OrderColumn_2 AS `OrderColumn` ;"; + var expected = "INSERT INTO `Table` ( `Name`, `Address` ) VALUES ROW ( @Name, @Address ) , " + + "ROW ( @Name_1, @Address_1 ) , ROW ( @Name_2, @Address_2 ) ; VALUES ROW ( LAST_INSERT_ID() + 0 ) " + + ", ROW ( LAST_INSERT_ID() + 1 ) , ROW ( LAST_INSERT_ID() + 2 ) ;"; // Assert Assert.AreEqual(expected, query); diff --git a/RepoDb.MySql/RepoDb.MySql/RepoDb.MySql.csproj b/RepoDb.MySql/RepoDb.MySql/RepoDb.MySql.csproj index 89cf0deb0..3a1285c9c 100644 --- a/RepoDb.MySql/RepoDb.MySql/RepoDb.MySql.csproj +++ b/RepoDb.MySql/RepoDb.MySql/RepoDb.MySql.csproj @@ -1,42 +1,26 @@  - - - RepoDb.MySql - netstandard2.0;net6.0;net7.0;net8.0 - 0.0.1 - 0.0.1 - 0.0.1 - A hybrid .NET ORM library for MySQL (using MySql.Data). - orm hybrid-orm micro-orm mysql - https://github.com/mikependon/RepoDb/tree/master/RepoDb.MySql - http://repodb.net/release/mysql - True - true - https://repodb.net/tutorial/get-started-mysql - - - - - - - - - - - - - - True - - - - - - - - - - - - + + RepoDb.MySql + netstandard2.0;net6.0;net7.0;net8.0 + annotations + A hybrid .NET ORM library for MySQL (using MySql.Data). + orm hybrid-orm micro-orm mysql + https://github.com/mikependon/RepoDb/tree/master/RepoDb.MySql + http://repodb.net/release/mysql + https://repodb.net/tutorial/get-started-mysql + + + + + + + + + + + + + + + diff --git a/RepoDb.MySql/RepoDb.MySql/StatementBuilders/MySqlStatementBuilder.cs b/RepoDb.MySql/RepoDb.MySql/StatementBuilders/MySqlStatementBuilder.cs index 4671883ce..28fa9590e 100644 --- a/RepoDb.MySql/RepoDb.MySql/StatementBuilders/MySqlStatementBuilder.cs +++ b/RepoDb.MySql/RepoDb.MySql/StatementBuilders/MySqlStatementBuilder.cs @@ -1,11 +1,10 @@ -using MySql.Data.MySqlClient; +using System; +using System.Collections.Generic; +using System.Linq; +using MySql.Data.MySqlClient; using RepoDb.Exceptions; using RepoDb.Extensions; using RepoDb.Interfaces; -using RepoDb.Resolvers; -using System; -using System.Collections.Generic; -using System.Linq; namespace RepoDb.StatementBuilders { @@ -259,35 +258,127 @@ public override string CreateInsertAll(string tableName, DbField identityField = null, string hints = null) { - // Call the base - var commandText = base.CreateInsertAll(tableName, - fields, - batchSize, - primaryField, - identityField, - hints); + // Ensure with guards + GuardTableName(tableName); + GuardHints(hints); + GuardPrimary(primaryField); + GuardIdentity(identityField); - // Variables needed - var commandTexts = new List(); - var splitted = commandText.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); - var keyColumn = GetReturnKeyColumnAsDbField(primaryField, identityField); + // Validate the multiple statement execution + ValidateMultipleStatementExecution(batchSize); + + // Verify the fields + if (fields?.Any() != true) + { + throw new EmptyException("The list of fields cannot be null or empty."); + } + + // Primary Key + if (primaryField != null && + primaryField.HasDefaultValue == false && + !string.Equals(primaryField.Name, identityField?.Name, StringComparison.OrdinalIgnoreCase)) + { + var isPresent = fields + .FirstOrDefault(f => + string.Equals(f.Name, primaryField.Name, StringComparison.OrdinalIgnoreCase)) != null; + + if (isPresent == false) + { + throw new PrimaryFieldNotFoundException($"As the primary field '{primaryField.Name}' is not an identity nor has a default value, it must be present on the insert operation."); + } + } + + // Insertable fields + var insertableFields = fields + .Where(f => + !string.Equals(f.Name, identityField?.Name, StringComparison.OrdinalIgnoreCase)); + + // Initialize the builder + var builder = new QueryBuilder(); + + // Build the query + builder.Clear(); + + // Compose + builder + .Insert() + .Into() + .TableNameFrom(tableName, DbSetting) + .HintsFrom(hints) + .OpenParen() + .FieldsFrom(insertableFields, DbSetting) + .CloseParen() + .Values(); // Iterate the indexes - for (var index = 0; index < splitted.Length; index++) + for (var index = 0; index < batchSize; index++) { - var returnValue = keyColumn != null ? - keyColumn.IsIdentity ? "LAST_INSERT_ID()" : - keyColumn.Name.AsParameter(index, DbSetting) : "NULL"; - var line = splitted[index].Trim(); - commandTexts.Add(string.Concat(line, " ; SELECT ", returnValue, " AS ", "Result".AsQuoted(DbSetting), ", ", - $"@__RepoDb_OrderColumn_{index} AS ", "OrderColumn".AsQuoted(DbSetting), " ;")); + builder + .WriteText("ROW") + .OpenParen() + .ParametersFrom(insertableFields, index, DbSetting) + .CloseParen(); + + if (index < batchSize - 1) + { + builder + .WriteText(","); + } } - // Set the command text - commandText = commandTexts.Join(" "); + // Close + builder + .End(); - // Return the query - return commandText; + var keyColumn = GetReturnKeyColumnAsDbField(primaryField, identityField); + + if (keyColumn?.IsIdentity == true) + { + builder + .Values(); + + for (var index = 0; index < batchSize; index++) + { + if (index > 0) + builder.WriteText(","); + + builder + .WriteText("ROW") + .OpenParen() + .WriteText("LAST_INSERT_ID() +") + .WriteText($"{index}") + .CloseParen(); + }; + + builder.End(); + + return builder.GetString(); + } + else + { + var commandText = builder.GetString(); + + // Variables needed + var commandTexts = new List(); + var splitted = commandText.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + + + // Iterate the indexes + for (var index = 0; index < splitted.Length; index++) + { + var returnValue = keyColumn != null ? + keyColumn.IsIdentity ? "LAST_INSERT_ID()" : + keyColumn.Name.AsParameter(index, DbSetting) : "NULL"; + var line = splitted[index].Trim(); + commandTexts.Add(string.Concat(line, " ; SELECT ", returnValue, " AS ", "Result".AsQuoted(DbSetting), ";")); + } + + // Set the command text + commandText = commandTexts.Join(" "); + + // Return the query + return commandText; + } } #endregion diff --git a/RepoDb.MySqlConnector/RepoDb.MySqlConnector.IntegrationTests/DbHelperTests.cs b/RepoDb.MySqlConnector/RepoDb.MySqlConnector.IntegrationTests/DbHelperTests.cs index 904a679fb..5a492d587 100644 --- a/RepoDb.MySqlConnector/RepoDb.MySqlConnector.IntegrationTests/DbHelperTests.cs +++ b/RepoDb.MySqlConnector/RepoDb.MySqlConnector.IntegrationTests/DbHelperTests.cs @@ -43,8 +43,9 @@ public void TestDbHelperGetFields() using (var reader = connection.ExecuteReader(@"SELECT COLUMN_NAME AS ColumnName FROM INFORMATION_SCHEMA.COLUMNS WHERE - TABLE_NAME = @TableName - ORDER BY ORDINAL_POSITION;", new { TableName = "CompleteTable" })) + TABLE_NAME = @TableName + AND TABLE_SCHEMA = @TableSchema + ORDER BY ORDINAL_POSITION;", new { TableName = "CompleteTable", TableSchema = connection.Database })) { var fieldCount = 0; @@ -120,8 +121,9 @@ public async Task TestDbHelperGetFieldsAsync() using (var reader = connection.ExecuteReader(@"SELECT COLUMN_NAME AS ColumnName FROM INFORMATION_SCHEMA.COLUMNS WHERE - TABLE_NAME = @TableName - ORDER BY ORDINAL_POSITION;", new { TableName = "CompleteTable" })) + TABLE_NAME = @TableName + AND TABLE_SCHEMA = @TableSchema + ORDER BY ORDINAL_POSITION;", new { TableName = "CompleteTable", TableSchema = connection.Database })) { var fieldCount = 0; diff --git a/RepoDb.MySqlConnector/RepoDb.MySqlConnector.IntegrationTests/RepoDb.MySqlConnector.IntegrationTests.csproj b/RepoDb.MySqlConnector/RepoDb.MySqlConnector.IntegrationTests/RepoDb.MySqlConnector.IntegrationTests.csproj index 2a790b290..a193c7474 100644 --- a/RepoDb.MySqlConnector/RepoDb.MySqlConnector.IntegrationTests/RepoDb.MySqlConnector.IntegrationTests.csproj +++ b/RepoDb.MySqlConnector/RepoDb.MySqlConnector.IntegrationTests/RepoDb.MySqlConnector.IntegrationTests.csproj @@ -1,25 +1,21 @@ - net6.0;net7.0;net8.0 false + true + true + true - portable true - - - - - + + - - - + \ No newline at end of file diff --git a/RepoDb.MySqlConnector/RepoDb.MySqlConnector.IntegrationTests/Setup/Database.cs b/RepoDb.MySqlConnector/RepoDb.MySqlConnector.IntegrationTests/Setup/Database.cs index 05beae2e8..40c987263 100644 --- a/RepoDb.MySqlConnector/RepoDb.MySqlConnector.IntegrationTests/Setup/Database.cs +++ b/RepoDb.MySqlConnector/RepoDb.MySqlConnector.IntegrationTests/Setup/Database.cs @@ -1,7 +1,7 @@ -using RepoDb.MySqlConnector.IntegrationTests.Models; -using MySqlConnector; -using System; +using System; using System.Collections.Generic; +using MySqlConnector; +using RepoDb.MySqlConnector.IntegrationTests.Models; namespace RepoDb.MySqlConnector.IntegrationTests.Setup { @@ -25,13 +25,17 @@ public static class Database public static void Initialize() { - // Get the connection string - var connectionStringForSys = Environment.GetEnvironmentVariable("REPODB_CONSTR_SYS", EnvironmentVariableTarget.Process); - var connectionString = Environment.GetEnvironmentVariable("REPODB_CONSTR", EnvironmentVariableTarget.Process); - - // Set the connection string - ConnectionStringForSys = (connectionStringForSys ?? @"Server=localhost;Database=sys;Uid=user;Pwd=Password123;"); - ConnectionString = (connectionString ?? @"Server=localhost;Database=RepoDb;Uid=user;Pwd=Password123;"); + ConnectionStringForSys = + Environment.GetEnvironmentVariable("REPODB_MYSQL_CONSTR_SYS") + ?? Environment.GetEnvironmentVariable("REPODB_CONSTR_SYS") + // ?? @"Server=127.0.0.1;Port=43306;Database=sys;User ID=root;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" // Docker test configuration + ?? @"Server=localhost;Database=sys;Uid=user;Pwd=Password123;"; + + ConnectionString = + Environment.GetEnvironmentVariable("REPODB_MYSQL_CONSTR_REPODBTEST") + ?? Environment.GetEnvironmentVariable("REPODB_CONSTR") + // ?? @"Server=127.0.0.1;Port=43306;Database=RepoDbTest;User ID=root;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" // Docker test configuration + ?? @"Server=localhost;Database=RepoDbTest;Uid=user;Pwd=Password123;"; // Initialize MySql GlobalConfiguration @@ -90,7 +94,8 @@ private static void CreateDatabase() { using (var connection = new MySqlConnection(ConnectionStringForSys)) { - connection.ExecuteNonQuery(@"CREATE SCHEMA IF NOT EXISTS `RepoDb`;"); + connection.ExecuteNonQuery(@"CREATE DATABASE IF NOT EXISTS `RepoDbTest`;"); + connection.ExecuteNonQuery(@"GRANT ALL Privileges on RepoDbTest.* to 'root'@'%';"); } } @@ -108,7 +113,7 @@ private static void CreateCompleteTable() { using (var connection = new MySqlConnection(ConnectionString)) { - connection.ExecuteNonQuery(@"CREATE TABLE IF NOT EXISTS `completetable` + connection.ExecuteNonQuery(@"CREATE TABLE IF NOT EXISTS `CompleteTable` ( `Id` bigint(20) NOT NULL AUTO_INCREMENT, `ColumnVarchar` varchar(256) DEFAULT NULL, @@ -161,7 +166,7 @@ private static void CreateNonIdentityCompleteTable() { using (var connection = new MySqlConnection(ConnectionString)) { - connection.ExecuteNonQuery(@"CREATE TABLE IF NOT EXISTS `nonidentitycompletetable` + connection.ExecuteNonQuery(@"CREATE TABLE IF NOT EXISTS `NonIdentityCompleteTable` ( `Id` bigint(20) NOT NULL, `ColumnVarchar` varchar(256) DEFAULT NULL, diff --git a/RepoDb.MySqlConnector/RepoDb.MySqlConnector.UnitTests/RepoDb.MySqlConnector.UnitTests.csproj b/RepoDb.MySqlConnector/RepoDb.MySqlConnector.UnitTests/RepoDb.MySqlConnector.UnitTests.csproj index cea7e2cb9..4d84ac012 100644 --- a/RepoDb.MySqlConnector/RepoDb.MySqlConnector.UnitTests/RepoDb.MySqlConnector.UnitTests.csproj +++ b/RepoDb.MySqlConnector/RepoDb.MySqlConnector.UnitTests/RepoDb.MySqlConnector.UnitTests.csproj @@ -1,18 +1,15 @@ - net6.0;net7.0;net8.0 false + true + true + true - - - - + - - - + \ No newline at end of file diff --git a/RepoDb.MySqlConnector/RepoDb.MySqlConnector.UnitTests/StatementBuilderTest.cs b/RepoDb.MySqlConnector/RepoDb.MySqlConnector.UnitTests/StatementBuilderTest.cs index 37a5870a4..d7a09b9c7 100644 --- a/RepoDb.MySqlConnector/RepoDb.MySqlConnector.UnitTests/StatementBuilderTest.cs +++ b/RepoDb.MySqlConnector/RepoDb.MySqlConnector.UnitTests/StatementBuilderTest.cs @@ -1,8 +1,8 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; using MySqlConnector; using RepoDb.Enumerations; using RepoDb.Exceptions; -using System; namespace RepoDb.MySql.UnitTests { @@ -309,16 +309,15 @@ public void TestMySqlStatementBuilderCreateInsertAll() 3, null, null); - var expected = "INSERT INTO `Table` ( `Id`, `Name`, `Address` ) VALUES ( @Id, @Name, @Address ) ; SELECT NULL AS `Result`, @__RepoDb_OrderColumn_0 AS `OrderColumn` ; " + - "INSERT INTO `Table` ( `Id`, `Name`, `Address` ) VALUES ( @Id_1, @Name_1, @Address_1 ) ; SELECT NULL AS `Result`, @__RepoDb_OrderColumn_1 AS `OrderColumn` ; " + - "INSERT INTO `Table` ( `Id`, `Name`, `Address` ) VALUES ( @Id_2, @Name_2, @Address_2 ) ; SELECT NULL AS `Result`, @__RepoDb_OrderColumn_2 AS `OrderColumn` ;"; + var expected = "INSERT INTO `Table` ( `Id`, `Name`, `Address` ) VALUES ROW ( @Id, @Name, @Address ) , " + + "ROW ( @Id_1, @Name_1, @Address_1 ) , ROW ( @Id_2, @Name_2, @Address_2 ) ; SELECT NULL AS `Result`;"; // Assert Assert.AreEqual(expected, query); } [TestMethod] - public void TestMySqlStatementBuilderCreateInserAlltWithPrimary() + public void TestMySqlStatementBuilderCreateInsertAllWithPrimary() { // Setup var builder = StatementBuilderMapper.Get(); @@ -329,9 +328,8 @@ public void TestMySqlStatementBuilderCreateInserAlltWithPrimary() 3, new DbField("Id", true, false, false, typeof(int), null, null, null, null, false), null); - var expected = "INSERT INTO `Table` ( `Id`, `Name`, `Address` ) VALUES ( @Id, @Name, @Address ) ; SELECT @Id AS `Result`, @__RepoDb_OrderColumn_0 AS `OrderColumn` ; " + - "INSERT INTO `Table` ( `Id`, `Name`, `Address` ) VALUES ( @Id_1, @Name_1, @Address_1 ) ; SELECT @Id_1 AS `Result`, @__RepoDb_OrderColumn_1 AS `OrderColumn` ; " + - "INSERT INTO `Table` ( `Id`, `Name`, `Address` ) VALUES ( @Id_2, @Name_2, @Address_2 ) ; SELECT @Id_2 AS `Result`, @__RepoDb_OrderColumn_2 AS `OrderColumn` ;"; + var expected = "INSERT INTO `Table` ( `Id`, `Name`, `Address` ) VALUES ROW ( @Id, @Name, @Address ) , ROW ( @Id_1, @Name_1, @Address_1 ) , " + + "ROW ( @Id_2, @Name_2, @Address_2 ) ; SELECT @Id AS `Result`;"; // Assert Assert.AreEqual(expected, query); @@ -349,9 +347,8 @@ public void TestMySqlStatementBuilderCreateInsertAllWithIdentity() 3, null, new DbField("Id", false, true, false, typeof(int), null, null, null, null, false)); - var expected = "INSERT INTO `Table` ( `Name`, `Address` ) VALUES ( @Name, @Address ) ; SELECT LAST_INSERT_ID() AS `Result`, @__RepoDb_OrderColumn_0 AS `OrderColumn` ; " + - "INSERT INTO `Table` ( `Name`, `Address` ) VALUES ( @Name_1, @Address_1 ) ; SELECT LAST_INSERT_ID() AS `Result`, @__RepoDb_OrderColumn_1 AS `OrderColumn` ; " + - "INSERT INTO `Table` ( `Name`, `Address` ) VALUES ( @Name_2, @Address_2 ) ; SELECT LAST_INSERT_ID() AS `Result`, @__RepoDb_OrderColumn_2 AS `OrderColumn` ;"; + var expected = "INSERT INTO `Table` ( `Name`, `Address` ) VALUES ROW ( @Name, @Address ) , ROW ( @Name_1, @Address_1 ) , " + + "ROW ( @Name_2, @Address_2 ) ; VALUES ROW ( LAST_INSERT_ID() + 0 ) , ROW ( LAST_INSERT_ID() + 1 ) , ROW ( LAST_INSERT_ID() + 2 ) ;"; // Assert Assert.AreEqual(expected, query); diff --git a/RepoDb.MySqlConnector/RepoDb.MySqlConnector/RepoDb.MySqlConnector.csproj b/RepoDb.MySqlConnector/RepoDb.MySqlConnector/RepoDb.MySqlConnector.csproj index fec5b91c8..3ea8b99b3 100644 --- a/RepoDb.MySqlConnector/RepoDb.MySqlConnector/RepoDb.MySqlConnector.csproj +++ b/RepoDb.MySqlConnector/RepoDb.MySqlConnector/RepoDb.MySqlConnector.csproj @@ -1,42 +1,25 @@ - - - RepoDb.MySqlConnector - netstandard2.0;net6.0;net7.0;net8.0 - 0.0.1 - 0.0.1 - 0.0.1 - A hybrid .NET ORM library for MySQL (using MySqlConnector). - orm hybrid-orm micro-orm mysql mysqlconnector - https://github.com/mikependon/RepoDb/tree/master/RepoDb.MySqlConnector - http://repodb.net/release/mysqlconnector - True - true - https://repodb.net/tutorial/get-started-mysql - - - - - - - - - - - - - - True - - - - - - - - - - - - - + + RepoDb.MySqlConnector + netstandard2.0;net6.0;net7.0;net8.0 + annotations + A hybrid .NET ORM library for MySQL (using MySqlConnector). + orm hybrid-orm micro-orm mysql mysqlconnector + https://github.com/mikependon/RepoDb/tree/master/RepoDb.MySqlConnector + http://repodb.net/release/mysqlconnector + https://repodb.net/tutorial/get-started-mysql + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/RepoDb.MySqlConnector/RepoDb.MySqlConnector/StatementBuilders/MySqlConnectorStatementBuilder.cs b/RepoDb.MySqlConnector/RepoDb.MySqlConnector/StatementBuilders/MySqlConnectorStatementBuilder.cs index cba042704..46ea2ff27 100644 --- a/RepoDb.MySqlConnector/RepoDb.MySqlConnector/StatementBuilders/MySqlConnectorStatementBuilder.cs +++ b/RepoDb.MySqlConnector/RepoDb.MySqlConnector/StatementBuilders/MySqlConnectorStatementBuilder.cs @@ -1,10 +1,10 @@ -using MySqlConnector; +using System; +using System.Collections.Generic; +using System.Linq; +using MySqlConnector; using RepoDb.Exceptions; using RepoDb.Extensions; using RepoDb.Interfaces; -using System; -using System.Collections.Generic; -using System.Linq; namespace RepoDb.StatementBuilders { @@ -252,41 +252,133 @@ public override string CreateInsert(string tableName, /// The table hints to be used. /// A sql statement for insert operation. public override string CreateInsertAll(string tableName, - IEnumerable fields = null, - int batchSize = 1, - DbField primaryField = null, - DbField identityField = null, - string hints = null) + IEnumerable fields = null, + int batchSize = 1, + DbField primaryField = null, + DbField identityField = null, + string hints = null) { - // Call the base - var commandText = base.CreateInsertAll(tableName, - fields, - batchSize, - primaryField, - identityField, - hints); + // Ensure with guards + GuardTableName(tableName); + GuardHints(hints); + GuardPrimary(primaryField); + GuardIdentity(identityField); - // Variables needed - var commandTexts = new List(); - var splitted = commandText.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); - var keyColumn = GetReturnKeyColumnAsDbField(primaryField, identityField); + // Validate the multiple statement execution + ValidateMultipleStatementExecution(batchSize); + + // Verify the fields + if (fields?.Any() != true) + { + throw new EmptyException("The list of fields cannot be null or empty."); + } + + // Primary Key + if (primaryField != null && + primaryField.HasDefaultValue == false && + !string.Equals(primaryField.Name, identityField?.Name, StringComparison.OrdinalIgnoreCase)) + { + var isPresent = fields + .FirstOrDefault(f => + string.Equals(f.Name, primaryField.Name, StringComparison.OrdinalIgnoreCase)) != null; + + if (isPresent == false) + { + throw new PrimaryFieldNotFoundException($"As the primary field '{primaryField.Name}' is not an identity nor has a default value, it must be present on the insert operation."); + } + } + + // Insertable fields + var insertableFields = fields + .Where(f => + !string.Equals(f.Name, identityField?.Name, StringComparison.OrdinalIgnoreCase)); + + // Initialize the builder + var builder = new QueryBuilder(); + + // Build the query + builder.Clear(); + + // Compose + builder + .Insert() + .Into() + .TableNameFrom(tableName, DbSetting) + .HintsFrom(hints) + .OpenParen() + .FieldsFrom(insertableFields, DbSetting) + .CloseParen() + .Values(); // Iterate the indexes - for (var index = 0; index < splitted.Length; index++) + for (var index = 0; index < batchSize; index++) { - var returnValue = keyColumn != null ? - keyColumn.IsIdentity ? "LAST_INSERT_ID()" : - keyColumn.Name.AsParameter(index, DbSetting) : "NULL"; - var line = splitted[index].Trim(); - commandTexts.Add(string.Concat(line, " ; SELECT ", returnValue, " AS ", "Result".AsQuoted(DbSetting), ", ", - $"@__RepoDb_OrderColumn_{index} AS ", "OrderColumn".AsQuoted(DbSetting), " ;")); + builder + .WriteText("ROW") + .OpenParen() + .ParametersFrom(insertableFields, index, DbSetting) + .CloseParen(); + + if (index < batchSize - 1) + { + builder + .WriteText(","); + } } - // Set the command text - commandText = commandTexts.Join(" "); + // Close + builder + .End(); - // Return the query - return commandText; + var keyColumn = GetReturnKeyColumnAsDbField(primaryField, identityField); + + if (keyColumn?.IsIdentity == true) + { + builder + .Values(); + + for (var index = 0; index < batchSize; index++) + { + if (index > 0) + builder.WriteText(","); + + builder + .WriteText("ROW") + .OpenParen() + .WriteText("LAST_INSERT_ID() +") + .WriteText($"{index}") + .CloseParen(); + }; + + builder.End(); + + return builder.GetString(); + } + else + { + var commandText = builder.GetString(); + + // Variables needed + var commandTexts = new List(); + var splitted = commandText.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + + + // Iterate the indexes + for (var index = 0; index < splitted.Length; index++) + { + var returnValue = keyColumn != null ? + keyColumn.IsIdentity ? "LAST_INSERT_ID()" : + keyColumn.Name.AsParameter(index, DbSetting) : "NULL"; + var line = splitted[index].Trim(); + commandTexts.Add(string.Concat(line, " ; SELECT ", returnValue, " AS ", "Result".AsQuoted(DbSetting), ";")); + } + + // Set the command text + commandText = commandTexts.Join(" "); + + // Return the query + return commandText; + } } #endregion diff --git a/RepoDb.PostgreSql/RepoDb.PostgreSql.IntegrationTests/RepoDb.PostgreSql.IntegrationTests.csproj b/RepoDb.PostgreSql/RepoDb.PostgreSql.IntegrationTests/RepoDb.PostgreSql.IntegrationTests.csproj index 34ddb070b..68f6bee3c 100644 --- a/RepoDb.PostgreSql/RepoDb.PostgreSql.IntegrationTests/RepoDb.PostgreSql.IntegrationTests.csproj +++ b/RepoDb.PostgreSql/RepoDb.PostgreSql.IntegrationTests/RepoDb.PostgreSql.IntegrationTests.csproj @@ -1,24 +1,17 @@  - net6.0;net7.0;net8.0 false + true + true + true - - - - - + + - - - - - - + - - + \ No newline at end of file diff --git a/RepoDb.PostgreSql/RepoDb.PostgreSql.IntegrationTests/Setup/Database.cs b/RepoDb.PostgreSql/RepoDb.PostgreSql.IntegrationTests/Setup/Database.cs index 30052c3ff..f85b2af2f 100644 --- a/RepoDb.PostgreSql/RepoDb.PostgreSql.IntegrationTests/Setup/Database.cs +++ b/RepoDb.PostgreSql/RepoDb.PostgreSql.IntegrationTests/Setup/Database.cs @@ -1,7 +1,7 @@ -using RepoDb.PostgreSql.IntegrationTests.Models; -using Npgsql; -using System; +using System; using System.Collections.Generic; +using Npgsql; +using RepoDb.PostgreSql.IntegrationTests.Models; namespace RepoDb.PostgreSql.IntegrationTests.Setup { @@ -12,7 +12,7 @@ public static class Database /// /// Gets or sets the connection string to be used for Postgres database. /// - public static string ConnectionStringForPosgres { get; private set; } + public static string ConnectionStringForPostgres { get; private set; } /// /// Gets or sets the connection string to be used. @@ -25,15 +25,19 @@ public static class Database public static void Initialize() { - // Check the connection string - var connectionStringForPosgres = Environment.GetEnvironmentVariable("REPODB_CONSTR_POSTGRESDB", EnvironmentVariableTarget.Process); - var connectionString = Environment.GetEnvironmentVariable("REPODB_CONSTR", EnvironmentVariableTarget.Process); - // Master connection - ConnectionStringForPosgres = (connectionStringForPosgres ?? "Server=127.0.0.1;Port=5432;Database=postgres;User Id=postgres;Password=Password123;"); + ConnectionStringForPostgres = + Environment.GetEnvironmentVariable("REPODB_POSTGRESQL_CONSTR_POSTGRESDB") + ?? Environment.GetEnvironmentVariable("REPODB_CONSTR_POSTGRESDB") + // ?? "Server=127.0.0.1;Port=45432;Database=postgres;User Id=postgres;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" // Docker test configuration + ?? "Server=127.0.0.1;Port=5432;Database=postgres;User Id=postgres;Password=Password123;"; // RepoDb connection - ConnectionString = (connectionString ?? "Server=127.0.0.1;Port=5432;Database=RepoDb;User Id=postgres;Password=Password123;"); + ConnectionString = + Environment.GetEnvironmentVariable("REPODB_POSTGRESQL_CONSTR") + ?? Environment.GetEnvironmentVariable("REPODB_CONSTR") + // ?? "Server=127.0.0.1;Port=45432;Database=RepoDb;User Id=postgres;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" // Docker test configuration + ?? "Server=127.0.0.1;Port=5432;Database=RepoDb;User Id=postgres;Password=Password123;"; // For >= v6.0.0: To reutilize the legacy behavior // https://github.com/abpframework/abp/issues/10273 @@ -67,7 +71,7 @@ public static void Cleanup() private static void CreateDatabase() { - using (var connection = new NpgsqlConnection(ConnectionStringForPosgres)) + using (var connection = new NpgsqlConnection(ConnectionStringForPostgres)) { var recordCount = connection.ExecuteScalar("SELECT COUNT(*) FROM pg_database WHERE datname = 'RepoDb';"); if (recordCount <= 0) diff --git a/RepoDb.PostgreSql/RepoDb.PostgreSql.UnitTests/RepoDb.PostgreSql.UnitTests.csproj b/RepoDb.PostgreSql/RepoDb.PostgreSql.UnitTests/RepoDb.PostgreSql.UnitTests.csproj index f0bedfcc8..d7a0b27f6 100644 --- a/RepoDb.PostgreSql/RepoDb.PostgreSql.UnitTests/RepoDb.PostgreSql.UnitTests.csproj +++ b/RepoDb.PostgreSql/RepoDb.PostgreSql.UnitTests/RepoDb.PostgreSql.UnitTests.csproj @@ -1,22 +1,19 @@  - net6.0;net7.0;net8.0 false + true + true + true - - - - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + \ No newline at end of file diff --git a/RepoDb.PostgreSql/RepoDb.PostgreSql/RepoDb.PostgreSql.csproj b/RepoDb.PostgreSql/RepoDb.PostgreSql/RepoDb.PostgreSql.csproj index d718893d8..2359d738b 100644 --- a/RepoDb.PostgreSql/RepoDb.PostgreSql/RepoDb.PostgreSql.csproj +++ b/RepoDb.PostgreSql/RepoDb.PostgreSql/RepoDb.PostgreSql.csproj @@ -1,42 +1,26 @@  - - - RepoDb.PostgreSql - netstandard2.0;net6.0;net7.0;net8.0 - 0.0.1 - 0.0.1 - 0.0.1 - A hybrid .NET ORM library for PostgreSQL. - orm hybrid-orm micro-orm postgresql npgsql - https://github.com/mikependon/RepoDb/tree/master/RepoDb.PostgreSql - http://repodb.net/release/postgresql - True - true - https://repodb.net/tutorial/get-started-postgresql - - - - - - - - - - - - - - - - - - True - - - - - - - - + + RepoDb.PostgreSql + netstandard2.0;net6.0;net7.0;net8.0 + annotations + A hybrid .NET ORM library for PostgreSQL. + orm hybrid-orm micro-orm postgresql npgsql + https://github.com/mikependon/RepoDb/tree/master/RepoDb.PostgreSql + http://repodb.net/release/postgresql + https://repodb.net/tutorial/get-started-postgresql + + + + + + + + + + + + + + + diff --git a/RepoDb.SQLite.System/RepoDb.SQLite.System.IntegrationTests/RepoDb.SQLite.System.IntegrationTests.csproj b/RepoDb.SQLite.System/RepoDb.SQLite.System.IntegrationTests/RepoDb.SQLite.System.IntegrationTests.csproj index 257e0b44e..30192c6a8 100644 --- a/RepoDb.SQLite.System/RepoDb.SQLite.System.IntegrationTests/RepoDb.SQLite.System.IntegrationTests.csproj +++ b/RepoDb.SQLite.System/RepoDb.SQLite.System.IntegrationTests/RepoDb.SQLite.System.IntegrationTests.csproj @@ -1,18 +1,15 @@ - net6.0;net7.0;net8.0 false + true + true + true - - - - + - - - + \ No newline at end of file diff --git a/RepoDb.SQLite.System/RepoDb.SQLite.System.UnitTests/RepoDb.SQLite.System.UnitTests.csproj b/RepoDb.SQLite.System/RepoDb.SQLite.System.UnitTests/RepoDb.SQLite.System.UnitTests.csproj index 257e0b44e..30192c6a8 100644 --- a/RepoDb.SQLite.System/RepoDb.SQLite.System.UnitTests/RepoDb.SQLite.System.UnitTests.csproj +++ b/RepoDb.SQLite.System/RepoDb.SQLite.System.UnitTests/RepoDb.SQLite.System.UnitTests.csproj @@ -1,18 +1,15 @@ - net6.0;net7.0;net8.0 false + true + true + true - - - - + - - - + \ No newline at end of file diff --git a/RepoDb.SQLite.System/RepoDb.SQLite.System.UnitTests/StatementBuilderTest.cs b/RepoDb.SQLite.System/RepoDb.SQLite.System.UnitTests/StatementBuilderTest.cs index e4dd31378..e37a34f69 100644 --- a/RepoDb.SQLite.System/RepoDb.SQLite.System.UnitTests/StatementBuilderTest.cs +++ b/RepoDb.SQLite.System/RepoDb.SQLite.System.UnitTests/StatementBuilderTest.cs @@ -231,9 +231,7 @@ public void TestSdsSqLiteStatementBuilderCreateInsertAll() 3, null, null); - var expected = "INSERT INTO [Table] ( [Id], [Name], [Address] ) VALUES ( @Id, @Name, @Address ) ; SELECT NULL AS [Result], @__RepoDb_OrderColumn_0 AS [OrderColumn] ; " + - "INSERT INTO [Table] ( [Id], [Name], [Address] ) VALUES ( @Id_1, @Name_1, @Address_1 ) ; SELECT NULL AS [Result], @__RepoDb_OrderColumn_1 AS [OrderColumn] ; " + - "INSERT INTO [Table] ( [Id], [Name], [Address] ) VALUES ( @Id_2, @Name_2, @Address_2 ) ; SELECT NULL AS [Result], @__RepoDb_OrderColumn_2 AS [OrderColumn] ;"; + var expected = "INSERT INTO [Table] ( [Id], [Name], [Address] ) VALUES ( @Id, @Name, @Address ) , ( @Id_1, @Name_1, @Address_1 ) , ( @Id_2, @Name_2, @Address_2 ) ;"; // Assert Assert.AreEqual(expected, query); @@ -251,9 +249,8 @@ public void TestSdsSqLiteStatementBuilderCreateInserAlltWithPrimary() 3, new DbField("Id", true, false, false, typeof(int), null, null, null, null, false), null); - var expected = "INSERT INTO [Table] ( [Id], [Name], [Address] ) VALUES ( @Id, @Name, @Address ) ; SELECT CAST(@Id AS INT) AS [Result], @__RepoDb_OrderColumn_0 AS [OrderColumn] ; " + - "INSERT INTO [Table] ( [Id], [Name], [Address] ) VALUES ( @Id_1, @Name_1, @Address_1 ) ; SELECT CAST(@Id_1 AS INT) AS [Result], @__RepoDb_OrderColumn_1 AS [OrderColumn] ; " + - "INSERT INTO [Table] ( [Id], [Name], [Address] ) VALUES ( @Id_2, @Name_2, @Address_2 ) ; SELECT CAST(@Id_2 AS INT) AS [Result], @__RepoDb_OrderColumn_2 AS [OrderColumn] ;"; + var expected = "INSERT INTO [Table] ( [Id], [Name], [Address] ) VALUES ( @Id, @Name, @Address ) ," + + " ( @Id_1, @Name_1, @Address_1 ) , ( @Id_2, @Name_2, @Address_2 ) RETURNING CAST([Id] AS INT) AS [Result] ;"; // Assert Assert.AreEqual(expected, query); @@ -271,9 +268,7 @@ public void TestSdsSqLiteStatementBuilderCreateInsertAllWithIdentity() 3, null, new DbField("Id", false, true, false, typeof(int), null, null, null, null, false)); - var expected = "INSERT INTO [Table] ( [Name], [Address] ) VALUES ( @Name, @Address ) ; SELECT CAST(last_insert_rowid() AS INT) AS [Result], @__RepoDb_OrderColumn_0 AS [OrderColumn] ; " + - "INSERT INTO [Table] ( [Name], [Address] ) VALUES ( @Name_1, @Address_1 ) ; SELECT CAST(last_insert_rowid() AS INT) AS [Result], @__RepoDb_OrderColumn_1 AS [OrderColumn] ; " + - "INSERT INTO [Table] ( [Name], [Address] ) VALUES ( @Name_2, @Address_2 ) ; SELECT CAST(last_insert_rowid() AS INT) AS [Result], @__RepoDb_OrderColumn_2 AS [OrderColumn] ;"; + var expected = "INSERT INTO [Table] ( [Name], [Address] ) VALUES ( @Name, @Address ) , ( @Name_1, @Address_1 ) , ( @Name_2, @Address_2 ) RETURNING CAST([Id] AS INT) AS [Result] ;"; // Assert Assert.AreEqual(expected, query); diff --git a/RepoDb.SQLite.System/RepoDb.SQLite.System/RepoDb.SQLite.System.csproj b/RepoDb.SQLite.System/RepoDb.SQLite.System/RepoDb.SQLite.System.csproj index 83fa47aad..8efb6749e 100644 --- a/RepoDb.SQLite.System/RepoDb.SQLite.System/RepoDb.SQLite.System.csproj +++ b/RepoDb.SQLite.System/RepoDb.SQLite.System/RepoDb.SQLite.System.csproj @@ -1,44 +1,27 @@  - - - RepoDb.SQLite.System - netstandard2.0;net6.0;net7.0;net8.0 - 0.0.1 - 0.0.1 - 0.0.1 - A hybrid .NET ORM library for SQLite (using System.Data.SQLite.Core). - orm hybrid-orm micro-orm sqlite - https://github.com/mikependon/RepoDb/tree/master/RepoDb.SqLite - http://repodb.net/release/sqlite - True - true - https://repodb.net/tutorial/get-started-sqlite - - - - - - - - - - - - - - - - - - - - True - - - - - - - - + + RepoDb.SQLite.System + netstandard2.0;net6.0;net7.0;net8.0 + annotations + A hybrid .NET ORM library for SQLite (using System.Data.SQLite.Core). + orm hybrid-orm micro-orm sqlite + https://github.com/mikependon/RepoDb/tree/master/RepoDb.SqLite + http://repodb.net/release/sqlite + https://repodb.net/tutorial/get-started-sqlite + + + + + + + + + + + + + + + + diff --git a/RepoDb.SQLite.System/RepoDb.SQLite.System/StatementBuilders/SqLiteStatementBuilder.cs b/RepoDb.SQLite.System/RepoDb.SQLite.System/StatementBuilders/SqLiteStatementBuilder.cs index e64c5271e..6ad1aa3b9 100644 --- a/RepoDb.SQLite.System/RepoDb.SQLite.System/StatementBuilders/SqLiteStatementBuilder.cs +++ b/RepoDb.SQLite.System/RepoDb.SQLite.System/StatementBuilders/SqLiteStatementBuilder.cs @@ -210,39 +210,94 @@ public override string CreateInsertAll(string tableName, DbField identityField = null, string hints = null) { - // Call the base - var commandText = base.CreateInsertAll(tableName, - fields, - batchSize, - primaryField, - identityField, - hints); + // Ensure with guards + GuardTableName(tableName); + GuardHints(hints); + GuardPrimary(primaryField); + GuardIdentity(identityField); - // Variables needed - var keyColumn = GetReturnKeyColumnAsDbField(primaryField, identityField); - var databaseType = GetDatabaseType(keyColumn); + // Validate the multiple statement execution + ValidateMultipleStatementExecution(batchSize); - // Set the return value - var commandTexts = new List(); - var splitted = commandText.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + // Verify the fields + if (fields?.Any() != true) + { + throw new EmptyException("The list of fields cannot be null or empty."); + } + + // Primary Key + if (primaryField != null && + primaryField.HasDefaultValue == false && + !string.Equals(primaryField.Name, identityField?.Name, StringComparison.OrdinalIgnoreCase)) + { + var isPresent = fields + .FirstOrDefault(f => + string.Equals(f.Name, primaryField.Name, StringComparison.OrdinalIgnoreCase)) != null; + + if (isPresent == false) + { + throw new PrimaryFieldNotFoundException($"As the primary field '{primaryField.Name}' is not an identity nor has a default value, it must be present on the insert operation."); + } + } + + // Insertable fields + var insertableFields = fields + .Where(f => + !string.Equals(f.Name, identityField?.Name, StringComparison.OrdinalIgnoreCase)); + + // Initialize the builder + var builder = new QueryBuilder(); + + // Build the query + builder.Clear(); + + // Compose + builder + .Insert() + .Into() + .TableNameFrom(tableName, DbSetting) + .HintsFrom(hints) + .OpenParen() + .FieldsFrom(insertableFields, DbSetting) + .CloseParen() + .Values(); // Iterate the indexes - for (var index = 0; index < splitted.Length; index++) + for (var index = 0; index < batchSize; index++) { - var line = splitted[index].Trim(); - var columnName = keyColumn != null ? - keyColumn.IsIdentity ? - "last_insert_rowid()" : keyColumn.Name.AsParameter(index, DbSetting) : "NULL"; - var result = string.IsNullOrWhiteSpace(databaseType) ? - columnName : $"CAST({columnName} AS {databaseType})"; - commandTexts.Add(string.Concat(line, " ; SELECT ", result, " AS ", "Result".AsQuoted(DbSetting), $", {DbSetting.ParameterPrefix}__RepoDb_OrderColumn_{index} AS [OrderColumn] ;")); + builder + .OpenParen() + .ParametersFrom(insertableFields, index, DbSetting) + .CloseParen(); + + if (index < batchSize - 1) + { + builder + .WriteText(","); + } } - // Set the command text - commandText = commandTexts.Join(" "); + // Variables needed + var keyColumn = GetReturnKeyColumnAsDbField(primaryField, identityField); + + // Set the return value + if (keyColumn != null) + { + var dbType = new ClientTypeToDbTypeResolver().Resolve(keyColumn.Type); + var databaseType = (dbType != null) ? new DbTypeToSqLiteStringNameResolver().Resolve(dbType.Value) : null; + var returnValue = keyColumn == null ? "NULL" : + string.IsNullOrWhiteSpace(databaseType) ? + keyColumn.Name.AsQuoted(DbSetting) : + string.Concat("CAST(", keyColumn.Name.AsQuoted(DbSetting), " AS ", databaseType, ")"); + builder + .WriteText( + string.Concat("RETURNING ", returnValue, $" AS ", "Result".AsQuoted(DbSetting))); + } // Return the query - return commandText; + return builder + .End() + .GetString(); } #endregion diff --git a/RepoDb.SqlServer/RepoDb.SqlServer.IntegrationTests/AdditionalDbTypesTests.cs b/RepoDb.SqlServer/RepoDb.SqlServer.IntegrationTests/AdditionalDbTypesTests.cs index f982760b6..9544f291f 100644 --- a/RepoDb.SqlServer/RepoDb.SqlServer.IntegrationTests/AdditionalDbTypesTests.cs +++ b/RepoDb.SqlServer/RepoDb.SqlServer.IntegrationTests/AdditionalDbTypesTests.cs @@ -88,6 +88,55 @@ await connection.InsertAllAsync( Assert.IsTrue((await connection.QueryAsync(where: x => x.DateOnlyNullable == new DateOnly(2026, 1, 1), transaction: t)).Count() == 1); } + [TestMethod] + public async Task CompareValuesTests() + { + await using var connection = new SqlConnection(Database.ConnectionString); + await connection.OpenAsync(); + await using var t = await connection.BeginTransactionAsync(); + + await connection.InsertAllAsync( + new DateOnlyTestData[] { + new() + { + DateOnly = new DateOnly(2024,1,1), + DateOnlyNullable = null, + }, + new () + { + DateOnly = new DateOnly(2025,1,1), + DateOnlyNullable = new DateOnly(2026,1,1), + } + }, + transaction: t); + + + // This one used to fail with NotSupportedException as '!' was not interpreted correctly + var notEqualValue = new DateOnly(2024, 1, 1); + var n = await connection.UpdateAsync( + new() + { + DateOnly = new DateOnly(2027, 1, 1) + }, + where: QueryGroup.Parse(x => !(x.DateOnly == notEqualValue)), + fields: Field.Parse(x => x.DateOnly), + transaction: t); + + Assert.AreEqual(1, n); + + // This one used to fail by silently ignoring the '!(x.DateOnlyNullable == notEqualValue2)' part + var notEqualValue2 = new DateOnly(2029, 1, 1); + var n2 = await connection.UpdateAsync( + new() + { + DateOnly = new DateOnly(2030, 1, 1) + }, + where: QueryGroup.Parse(x => x.DateOnlyNullable == null || !(x.DateOnlyNullable == notEqualValue2)), + fields: Field.Parse(x => x.DateOnly), + transaction: t); + Assert.AreEqual(2, n2); + } + public class DateOnlyTestData diff --git a/RepoDb.SqlServer/RepoDb.SqlServer.IntegrationTests/RepoDb.SqlServer.IntegrationTests.csproj b/RepoDb.SqlServer/RepoDb.SqlServer.IntegrationTests/RepoDb.SqlServer.IntegrationTests.csproj index 78899859b..242671b07 100644 --- a/RepoDb.SqlServer/RepoDb.SqlServer.IntegrationTests/RepoDb.SqlServer.IntegrationTests.csproj +++ b/RepoDb.SqlServer/RepoDb.SqlServer.IntegrationTests/RepoDb.SqlServer.IntegrationTests.csproj @@ -1,23 +1,20 @@  - net6.0;net7.0;net8.0 false + true + true + true - - - - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + \ No newline at end of file diff --git a/RepoDb.SqlServer/RepoDb.SqlServer.IntegrationTests/Setup/Database.cs b/RepoDb.SqlServer/RepoDb.SqlServer.IntegrationTests/Setup/Database.cs index afa0dd673..dfea1149a 100644 --- a/RepoDb.SqlServer/RepoDb.SqlServer.IntegrationTests/Setup/Database.cs +++ b/RepoDb.SqlServer/RepoDb.SqlServer.IntegrationTests/Setup/Database.cs @@ -1,8 +1,8 @@ -using RepoDb.SqlServer.IntegrationTests.Models; -using Microsoft.Data.SqlClient; -using System; +using System; using System.Collections.Generic; using System.Data; +using Microsoft.Data.SqlClient; +using RepoDb.SqlServer.IntegrationTests.Models; namespace RepoDb.SqlServer.IntegrationTests.Setup { @@ -27,12 +27,18 @@ public static class Database public static void Initialize() { // Master connection - ConnectionStringForMaster = Environment.GetEnvironmentVariable("REPODB_CONSTR_MASTER", EnvironmentVariableTarget.Process) ?? - @"Server=(local);Database=master;Integrated Security=SSPI;TrustServerCertificate=True;"; + ConnectionStringForMaster = + Environment.GetEnvironmentVariable("REPODB_SQLSERVER_CONSTR_MASTER") + ?? Environment.GetEnvironmentVariable("REPODB_CONSTR_MASTER") + //?? @"Server=tcp:127.0.0.1,41433;Database=master;User ID=sa;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;TrustServerCertificate=True;" // Docker Test Configuration + ?? @"Server=(local);Database=master;Integrated Security=SSPI;TrustServerCertificate=True;"; // RepoDb connection - ConnectionString = Environment.GetEnvironmentVariable("REPODB_CONSTR", EnvironmentVariableTarget.Process) ?? - @"Server=(local);Database=RepoDbTest;Integrated Security=SSPI;TrustServerCertificate=True;"; + ConnectionString = + Environment.GetEnvironmentVariable("REPODB_SQLSERVER_CONSTR_REPODBTEST") + ?? Environment.GetEnvironmentVariable("REPODB_CONSTR") + //?? @"Server=tcp:127.0.0.1,41433;Database=RepoDbTest;User ID=sa;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;TrustServerCertificate=True;" // Docker Test Configuration + ?? @"Server=(local);Database=RepoDbTest;Integrated Security=SSPI;TrustServerCertificate=True;"; // Initialize the SqlServer GlobalConfiguration diff --git a/RepoDb.SqlServer/RepoDb.SqlServer.UnitTests/RepoDb.SqlServer.UnitTests.csproj b/RepoDb.SqlServer/RepoDb.SqlServer.UnitTests/RepoDb.SqlServer.UnitTests.csproj index 78899859b..242671b07 100644 --- a/RepoDb.SqlServer/RepoDb.SqlServer.UnitTests/RepoDb.SqlServer.UnitTests.csproj +++ b/RepoDb.SqlServer/RepoDb.SqlServer.UnitTests/RepoDb.SqlServer.UnitTests.csproj @@ -1,23 +1,20 @@  - net6.0;net7.0;net8.0 false + true + true + true - - - - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + \ No newline at end of file diff --git a/RepoDb.SqlServer/RepoDb.SqlServer/RepoDb.SqlServer.csproj b/RepoDb.SqlServer/RepoDb.SqlServer/RepoDb.SqlServer.csproj index b9574fc9a..105b90bfb 100644 --- a/RepoDb.SqlServer/RepoDb.SqlServer/RepoDb.SqlServer.csproj +++ b/RepoDb.SqlServer/RepoDb.SqlServer/RepoDb.SqlServer.csproj @@ -1,38 +1,22 @@  - - - RepoDb.SqlServer - netstandard2.0;net6.0;net7.0;net8.0 - 0.0.1 - 0.0.1 - 0.0.1 - A hybrid .NET ORM library for SQL Server. - orm hybrid-orm micro-orm sqlserver - https://github.com/mikependon/RepoDb/tree/master/RepoDb.SqlServer - http://repodb.net/release/sqlserver - true - true - https://repodb.net/tutorial/get-started-sqlserver - - - - - - - - - - - - - - True - - - - - - - - + + RepoDb.SqlServer + netstandard2.0;net6.0;net7.0;net8.0 + annotations + A hybrid .NET ORM library for SQL Server. + orm hybrid-orm micro-orm sqlserver + https://github.com/mikependon/RepoDb/tree/master/RepoDb.SqlServer + http://repodb.net/release/sqlserver + https://repodb.net/tutorial/get-started-sqlserver + + + + + + + + + + + diff --git a/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft.IntegrationTests/RepoDb.Sqlite.Microsoft.IntegrationTests.csproj b/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft.IntegrationTests/RepoDb.Sqlite.Microsoft.IntegrationTests.csproj index 7d49c82e8..35eb225e8 100644 --- a/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft.IntegrationTests/RepoDb.Sqlite.Microsoft.IntegrationTests.csproj +++ b/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft.IntegrationTests/RepoDb.Sqlite.Microsoft.IntegrationTests.csproj @@ -1,18 +1,15 @@  - net6.0;net7.0;net8.0 false + true + true + true - - - - + - - diff --git a/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft.UnitTests/RepoDb.Sqlite.Microsoft.UnitTests.csproj b/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft.UnitTests/RepoDb.Sqlite.Microsoft.UnitTests.csproj index 7d49c82e8..8f363be69 100644 --- a/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft.UnitTests/RepoDb.Sqlite.Microsoft.UnitTests.csproj +++ b/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft.UnitTests/RepoDb.Sqlite.Microsoft.UnitTests.csproj @@ -1,18 +1,12 @@  - net6.0;net7.0;net8.0 false - - - - + - - - + \ No newline at end of file diff --git a/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft.UnitTests/StatementBuilderTest.cs b/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft.UnitTests/StatementBuilderTest.cs index 5f77df74f..389fdc370 100644 --- a/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft.UnitTests/StatementBuilderTest.cs +++ b/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft.UnitTests/StatementBuilderTest.cs @@ -231,9 +231,7 @@ public void TestMdsSqLiteStatementBuilderCreateInsertAll() 3, null, null); - var expected = "INSERT INTO [Table] ( [Id], [Name], [Address] ) VALUES ( @Id, @Name, @Address ) ; SELECT NULL AS [Result], @__RepoDb_OrderColumn_0 AS [OrderColumn] ; " + - "INSERT INTO [Table] ( [Id], [Name], [Address] ) VALUES ( @Id_1, @Name_1, @Address_1 ) ; SELECT NULL AS [Result], @__RepoDb_OrderColumn_1 AS [OrderColumn] ; " + - "INSERT INTO [Table] ( [Id], [Name], [Address] ) VALUES ( @Id_2, @Name_2, @Address_2 ) ; SELECT NULL AS [Result], @__RepoDb_OrderColumn_2 AS [OrderColumn] ;"; + var expected = "INSERT INTO [Table] ( [Id], [Name], [Address] ) VALUES ( @Id, @Name, @Address ) , ( @Id_1, @Name_1, @Address_1 ) , ( @Id_2, @Name_2, @Address_2 ) ;"; // Assert Assert.AreEqual(expected, query); @@ -251,9 +249,8 @@ public void TestMdsSqLiteStatementBuilderCreateInserAlltWithPrimary() 3, new DbField("Id", true, false, false, typeof(int), null, null, null, null, false), null); - var expected = "INSERT INTO [Table] ( [Id], [Name], [Address] ) VALUES ( @Id, @Name, @Address ) ; SELECT CAST(@Id AS INT) AS [Result], @__RepoDb_OrderColumn_0 AS [OrderColumn] ; " + - "INSERT INTO [Table] ( [Id], [Name], [Address] ) VALUES ( @Id_1, @Name_1, @Address_1 ) ; SELECT CAST(@Id_1 AS INT) AS [Result], @__RepoDb_OrderColumn_1 AS [OrderColumn] ; " + - "INSERT INTO [Table] ( [Id], [Name], [Address] ) VALUES ( @Id_2, @Name_2, @Address_2 ) ; SELECT CAST(@Id_2 AS INT) AS [Result], @__RepoDb_OrderColumn_2 AS [OrderColumn] ;"; + var expected = "INSERT INTO [Table] ( [Id], [Name], [Address] ) VALUES ( @Id, @Name, @Address ) ," + + " ( @Id_1, @Name_1, @Address_1 ) , ( @Id_2, @Name_2, @Address_2 ) RETURNING CAST([Id] AS INT) AS [Result] ;"; // Assert Assert.AreEqual(expected, query); @@ -271,9 +268,7 @@ public void TestMdsSqLiteStatementBuilderCreateInsertAllWithIdentity() 3, null, new DbField("Id", false, true, false, typeof(int), null, null, null, null, false)); - var expected = "INSERT INTO [Table] ( [Name], [Address] ) VALUES ( @Name, @Address ) ; SELECT CAST(last_insert_rowid() AS INT) AS [Result], @__RepoDb_OrderColumn_0 AS [OrderColumn] ; " + - "INSERT INTO [Table] ( [Name], [Address] ) VALUES ( @Name_1, @Address_1 ) ; SELECT CAST(last_insert_rowid() AS INT) AS [Result], @__RepoDb_OrderColumn_1 AS [OrderColumn] ; " + - "INSERT INTO [Table] ( [Name], [Address] ) VALUES ( @Name_2, @Address_2 ) ; SELECT CAST(last_insert_rowid() AS INT) AS [Result], @__RepoDb_OrderColumn_2 AS [OrderColumn] ;"; + var expected = "INSERT INTO [Table] ( [Name], [Address] ) VALUES ( @Name, @Address ) , ( @Name_1, @Address_1 ) , ( @Name_2, @Address_2 ) RETURNING CAST([Id] AS INT) AS [Result] ;"; // Assert Assert.AreEqual(expected, query); diff --git a/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft.csproj b/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft.csproj index a1bdecab4..d66925373 100644 --- a/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft.csproj +++ b/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft.csproj @@ -1,46 +1,27 @@  - - - RepoDb.Sqlite.Microsoft - netstandard2.0;net6.0;net7.0;net8.0 - 0.0.1 - 0.0.1 - 0.0.1 - A hybrid .NET ORM library for SQLite (using Microsoft.Data.Sqlite). - orm hybrid-orm micro-orm sqlite - https://github.com/mikependon/RepoDb/tree/master/RepoDb.SqLite - http://repodb.net/release/sqlite - True - true - https://repodb.net/tutorial/get-started-sqlite - RepoDb.Sqlite.Microsoft - RepoDb.Sqlite.Microsoft - - - - - - - - - - - - - - - - - - - - True - - - - - - - - + + RepoDb.Sqlite.Microsoft + netstandard2.0;net6.0;net7.0;net8.0 + annotations + A hybrid .NET ORM library for SQLite (using Microsoft.Data.Sqlite). + orm hybrid-orm micro-orm sqlite + https://github.com/mikependon/RepoDb/tree/master/RepoDb.SqLite + http://repodb.net/release/sqlite + https://repodb.net/tutorial/get-started-sqlite + + + + + + + + + + + + + + + + diff --git a/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft/StatementBuilders/SqLiteStatementBuilder.cs b/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft/StatementBuilders/SqLiteStatementBuilder.cs index 92542a3f9..ff6095f7c 100644 --- a/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft/StatementBuilders/SqLiteStatementBuilder.cs +++ b/RepoDb.Sqlite.Microsoft/RepoDb.Sqlite.Microsoft/StatementBuilders/SqLiteStatementBuilder.cs @@ -210,39 +210,94 @@ public override string CreateInsertAll(string tableName, DbField identityField = null, string hints = null) { - // Call the base - var commandText = base.CreateInsertAll(tableName, - fields, - batchSize, - primaryField, - identityField, - hints); + // Ensure with guards + GuardTableName(tableName); + GuardHints(hints); + GuardPrimary(primaryField); + GuardIdentity(identityField); - // Variables needed - var keyColumn = GetReturnKeyColumnAsDbField(primaryField, identityField); - var databaseType = GetDatabaseType(keyColumn); + // Validate the multiple statement execution + ValidateMultipleStatementExecution(batchSize); - // Set the return value - var commandTexts = new List(); - var splitted = commandText.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + // Verify the fields + if (fields?.Any() != true) + { + throw new EmptyException("The list of fields cannot be null or empty."); + } + + // Primary Key + if (primaryField != null && + primaryField.HasDefaultValue == false && + !string.Equals(primaryField.Name, identityField?.Name, StringComparison.OrdinalIgnoreCase)) + { + var isPresent = fields + .FirstOrDefault(f => + string.Equals(f.Name, primaryField.Name, StringComparison.OrdinalIgnoreCase)) != null; + + if (isPresent == false) + { + throw new PrimaryFieldNotFoundException($"As the primary field '{primaryField.Name}' is not an identity nor has a default value, it must be present on the insert operation."); + } + } + + // Insertable fields + var insertableFields = fields + .Where(f => + !string.Equals(f.Name, identityField?.Name, StringComparison.OrdinalIgnoreCase)); + + // Initialize the builder + var builder = new QueryBuilder(); + + // Build the query + builder.Clear(); + + // Compose + builder + .Insert() + .Into() + .TableNameFrom(tableName, DbSetting) + .HintsFrom(hints) + .OpenParen() + .FieldsFrom(insertableFields, DbSetting) + .CloseParen() + .Values(); // Iterate the indexes - for (var index = 0; index < splitted.Length; index++) + for (var index = 0; index < batchSize; index++) { - var line = splitted[index].Trim(); - var columnName = keyColumn != null ? - keyColumn.IsIdentity ? - "last_insert_rowid()" : keyColumn.Name.AsParameter(index, DbSetting) : "NULL"; - var result = string.IsNullOrWhiteSpace(databaseType) ? - columnName : $"CAST({columnName} AS {databaseType})"; - commandTexts.Add(string.Concat(line, " ; SELECT ", result, " AS ", "Result".AsQuoted(DbSetting), $", {DbSetting.ParameterPrefix}__RepoDb_OrderColumn_{index} AS [OrderColumn] ;")); + builder + .OpenParen() + .ParametersFrom(insertableFields, index, DbSetting) + .CloseParen(); + + if (index < batchSize - 1) + { + builder + .WriteText(","); + } } - // Set the command text - commandText = commandTexts.Join(" "); + // Variables needed + var keyColumn = GetReturnKeyColumnAsDbField(primaryField, identityField); + + // Set the return value + if (keyColumn != null) + { + var dbType = new ClientTypeToDbTypeResolver().Resolve(keyColumn.Type); + var databaseType = (dbType != null) ? new DbTypeToSqLiteStringNameResolver().Resolve(dbType.Value) : null; + var returnValue = keyColumn == null ? "NULL" : + string.IsNullOrWhiteSpace(databaseType) ? + keyColumn.Name.AsQuoted(DbSetting) : + string.Concat("CAST(", keyColumn.Name.AsQuoted(DbSetting), " AS ", databaseType, ")"); + builder + .WriteText( + string.Concat("RETURNING ", returnValue, $" AS ", "Result".AsQuoted(DbSetting))); + } // Return the query - return commandText; + return builder + .End() + .GetString(); } #endregion diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..f0711955e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,23 @@ +services: + + mssql: + image: mcr.microsoft.com/mssql/server:2022-latest + ports: + - 127.0.0.1:41433:1433 + environment: + ACCEPT_EULA: true + MSSQL_SA_PASSWORD: ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2 + + postgresql: + image: postgres:latest + ports: + - 127.0.0.1:45432:5432 + environment: + POSTGRES_PASSWORD: ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2 + + mysql: + image: mysql:latest + ports: + - 127.0.0.1:43306:3306 + environment: + MYSQL_ROOT_PASSWORD: ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2 \ No newline at end of file diff --git a/test-docker.ps1 b/test-docker.ps1 new file mode 100644 index 000000000..aca7d25c6 --- /dev/null +++ b/test-docker.ps1 @@ -0,0 +1,31 @@ +# Start instances of all database engines in clean docker instances +docker compose down +docker compose up -d + +# Build all test project +foreach ($test in $tests) { + dotnet build $test -f $framework + if(-not $?){ + Exit(1) + } +} + +# SqlServer SA +$env:REPODB_SQLSERVER_CONSTR_MASTER="Server=tcp:127.0.0.1,41433;Database=master;User ID=sa;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;TrustServerCertificate=True;" +# RepoDb common integration tests +$env:REPODB_SQLSERVER_CONSTR_REPODB="Server=tcp:127.0.0.1,41433;Database=RepoDb;User ID=sa;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;TrustServerCertificate=True;" +# SqlServer Tests +$env:REPODB_SQLSERVER_CONSTR_REPODBTEST="Server=tcp:127.0.0.1,41433;Database=RepoDbTest;User ID=sa;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;TrustServerCertificate=True;" +$env:REPODB_POSTGRESQL_CONSTR_POSTGRESDB="Server=127.0.0.1;Port=45432;Database=postgres;User Id=postgres;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" +$env:REPODB_POSTGRESQL_CONSTR="Server=127.0.0.1;Port=45432;Database=RepoDb;User Id=postgres;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" +$env:REPODB_POSTGRESQL_CONSTR_BULK="Server=127.0.0.1;Port=45432;Database=RepoDbBulk;User Id=postgres;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" +$env:REPODB_MYSQL_CONSTR_SYS="Server=127.0.0.1;Port=43306;Database=sys;User ID=root;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" +# Mysql Tests +$env:REPODB_MYSQL_CONSTR_REPODB="Server=127.0.0.1;Port=43306;Database=RepoDb;User ID=root;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" +# MySqlConnector Tests +$env:REPODB_MYSQL_CONSTR_REPODBTEST="Server=127.0.0.1;Port=43306;Database=RepoDbTest;User ID=root;Password=ddd53e85-b15e-4da8-91e5-a7d3b00a0ab2;" + +dotnet test $test -f $framework --no-build -p:TestingPlatformShowTestsFailure=true -p:TestingPlatformCaptureOutput=false +if(-not $?){ + Exit(1) +}