diff --git a/README.md b/README.md index 62902e2..322e190 100644 --- a/README.md +++ b/README.md @@ -127,10 +127,10 @@ and https://entityframework-extensions.net/bulk-extensions), using optimized con Legend : * `PhenX_EntityFrameworkCore_BulkInsert`: this library - * `RawInsert`: no library, using the native provider API (SqlBulkCopy for SQL Server, BeginBinaryImport for PostgreSQL, raw inserts for SQLite) + * `RawInsert`: naive implementation without any library, using the native provider API (SqlBulkCopy for SQL Server, BeginBinaryImport for PostgreSQL, raw inserts for SQLite) * `Z_EntityFramework_Extensions_EFCore`: https://entityframework-extensions.net/bulk-extensions * `EFCore_BulkExtensions`: https://github.com/borisdj/EFCore.BulkExtensions - * `EFCore_SaveChanges`: EF Core SaveChanges classic method + * `Linq2Db`: https://github.com/linq2db/linq2db SQL Server results with 500 000 rows : @@ -144,6 +144,10 @@ SQLite results with 500 000 rows : ![bench-sqlite.png](https://raw.githubusercontent.com/PhenX/PhenX.EntityFrameworkCore.BulkInsert/refs/heads/master/images/bench-sqlite.png) +MySQL results with 500 000 rows : + +![bench-mysql.png](https://raw.githubusercontent.com/PhenX/PhenX.EntityFrameworkCore.BulkInsert/refs/heads/master/images/bench-mysql.png) + ## Contributing Contributions are welcome! Please open issues or submit pull requests for bug fixes, features, or documentation improvements. diff --git a/images/bench-mysql.png b/images/bench-mysql.png new file mode 100644 index 0000000..d6933b8 Binary files /dev/null and b/images/bench-mysql.png differ diff --git a/images/bench-postgresql.png b/images/bench-postgresql.png index c0bc7ff..36fb76d 100644 Binary files a/images/bench-postgresql.png and b/images/bench-postgresql.png differ diff --git a/images/bench-sqlite.png b/images/bench-sqlite.png index d43a047..cfcb1f6 100644 Binary files a/images/bench-sqlite.png and b/images/bench-sqlite.png differ diff --git a/images/bench-sqlserver.png b/images/bench-sqlserver.png index 2f739bb..a018287 100644 Binary files a/images/bench-sqlserver.png and b/images/bench-sqlserver.png differ diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs new file mode 100644 index 0000000..2916f6a --- /dev/null +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs @@ -0,0 +1,197 @@ +using System.Data; + +using Microsoft.Data.SqlClient; +using Microsoft.Data.Sqlite; +using Microsoft.EntityFrameworkCore; + +using MySqlConnector; + +using Npgsql; + +namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; + +public abstract partial class LibComparator +{ + private void RawInsertPostgreSql() + { + using var connection = (NpgsqlConnection)DbContext.Database.GetDbConnection(); + if (connection.State != ConnectionState.Open) + { + connection.Open(); + } + + const string copyCommand = $""" + COPY "{nameof(TestEntity)}" ( + "Name", + "Price", + "Identifier", + "CreatedAt", + "UpdatedAt", + "NumericEnumValue" + ) FROM STDIN (FORMAT BINARY) + """; + + using var writer = connection.BeginBinaryImport(copyCommand); + foreach (var entity in data) + { + writer.StartRow(); + writer.Write(entity.Name); + writer.Write(entity.Price); + writer.Write(entity.Identifier); + writer.Write(entity.CreatedAt); + writer.Write(entity.UpdatedAt); + writer.Write((int)entity.NumericEnumValue); + } + + writer.Complete(); + } + + private void RawInsertSqlite() + { + var connection = (SqliteConnection)DbContext.Database.GetDbConnection(); + if (connection.State != ConnectionState.Open) + { + connection.Open(); + } + + using var transaction = connection.BeginTransaction(); + using var command = connection.CreateCommand(); + command.CommandText = $""" + INSERT INTO "{nameof(TestEntity)}" ( + "Name", + "Price", + "Identifier", + "CreatedAt", + "UpdatedAt", + "NumericEnumValue" + ) VALUES (@Name, @Price, @Identifier, @CreatedAt, @UpdatedAt, @NumericEnumValue) + """; + + command.Parameters.Add(new SqliteParameter("@Name", DbType.String)); + command.Parameters.Add(new SqliteParameter("@Price", DbType.Decimal)); + command.Parameters.Add(new SqliteParameter("@Identifier", DbType.Guid)); + command.Parameters.Add(new SqliteParameter("@CreatedAt", DbType.DateTime)); + command.Parameters.Add(new SqliteParameter("@UpdatedAt", DbType.DateTime2)); + command.Parameters.Add(new SqliteParameter("@NumericEnumValue", DbType.Int32)); + + foreach (var entity in data) + { + command.Parameters["@Name"].Value = entity.Name; + command.Parameters["@Price"].Value = entity.Price; + command.Parameters["@Identifier"].Value = entity.Identifier; + command.Parameters["@CreatedAt"].Value = entity.CreatedAt; + command.Parameters["@UpdatedAt"].Value = entity.UpdatedAt; + command.Parameters["@NumericEnumValue"].Value = (int)entity.NumericEnumValue; + + command.ExecuteNonQuery(); + } + + transaction.Commit(); + } + + private void RawInsertSqlServer() + { + var connection = (SqlConnection)DbContext.Database.GetDbConnection(); + if (connection.State != ConnectionState.Open) + { + connection.Open(); + } + + using var bulkCopy = new SqlBulkCopy(connection); + + bulkCopy.DestinationTableName = nameof(TestEntity); + bulkCopy.BatchSize = 50_000; + bulkCopy.BulkCopyTimeout = 60; + + bulkCopy.ColumnMappings.Add("Name", "Name"); + bulkCopy.ColumnMappings.Add("Price", "Price"); + bulkCopy.ColumnMappings.Add("Identifier", "Identifier"); + bulkCopy.ColumnMappings.Add("CreatedAt", "CreatedAt"); + bulkCopy.ColumnMappings.Add("UpdatedAt", "UpdatedAt"); + bulkCopy.ColumnMappings.Add("NumericEnumValue", "NumericEnumValue"); + + var dataTable = new DataTable(); + dataTable.Columns.Add("Name", typeof(string)); + dataTable.Columns.Add("Price", typeof(decimal)); + dataTable.Columns.Add("Identifier", typeof(Guid)); + dataTable.Columns.Add("CreatedAt", typeof(DateTime)); + dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset)); + dataTable.Columns.Add("NumericEnumValue", typeof(int)); + + foreach (var entity in data) + { + var row = dataTable.NewRow(); + row["Name"] = entity.Name; + row["Price"] = entity.Price; + row["Identifier"] = entity.Identifier; + row["CreatedAt"] = entity.CreatedAt; + row["UpdatedAt"] = entity.UpdatedAt; + row["NumericEnumValue"] = (int)entity.NumericEnumValue; + dataTable.Rows.Add(row); + + if (dataTable.Rows.Count >= 50_000) + { + bulkCopy.WriteToServer(dataTable); + dataTable.Clear(); + } + } + + if (dataTable.Rows.Count > 0) + { + bulkCopy.WriteToServer(dataTable); + } + } + + private void RawInsertMySql() + { + var connection = (MySqlConnection)DbContext.Database.GetDbConnection(); + if (connection.State != ConnectionState.Open) + { + connection.Open(); + } + + var bulkCopy = new MySqlBulkCopy(connection); + + bulkCopy.DestinationTableName = nameof(TestEntity); + bulkCopy.BulkCopyTimeout = 60; + + var i = 0; + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(i++, "Name")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(i++, "Price")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(i++, "Identifier")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(i++, "CreatedAt")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(i++, "UpdatedAt")); + bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(i++, "NumericEnumValue")); + + var dataTable = new DataTable(); + dataTable.Columns.Add("Name", typeof(string)); + dataTable.Columns.Add("Price", typeof(decimal)); + dataTable.Columns.Add("Identifier", typeof(Guid)); + dataTable.Columns.Add("CreatedAt", typeof(DateTime)); + dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset)); + dataTable.Columns.Add("NumericEnumValue", typeof(int)); + + foreach (var entity in data) + { + var row = dataTable.NewRow(); + row["Name"] = entity.Name; + row["Price"] = entity.Price; + row["Identifier"] = entity.Identifier; + row["CreatedAt"] = entity.CreatedAt; + row["UpdatedAt"] = entity.UpdatedAt; + row["NumericEnumValue"] = (int)entity.NumericEnumValue; + dataTable.Rows.Add(row); + + if (dataTable.Rows.Count >= 50_000) + { + bulkCopy.WriteToServer(dataTable); + dataTable.Clear(); + } + } + + if (dataTable.Rows.Count > 0) + { + bulkCopy.WriteToServer(dataTable); + } + } +} diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs index 92fa230..3ac6947 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs @@ -1,24 +1,19 @@ -using System.Data; - using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Engines; using DotNet.Testcontainers.Containers; using EFCore.BulkExtensions; -using Microsoft.Data.SqlClient; -using Microsoft.Data.Sqlite; -using Microsoft.EntityFrameworkCore; - -using MySqlConnector; - -using Npgsql; +using LinqToDB.EntityFrameworkCore; using PhenX.EntityFrameworkCore.BulkInsert.Extensions; namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; -public abstract class LibComparator +[MemoryDiagnoser] +[SimpleJob(RunStrategy.ColdStart, launchCount: 1, warmupCount: 0, iterationCount: 5)] +public abstract partial class LibComparator { [Params(500_000/*, 1_000_000/*, 10_000_000*/)] public int N; @@ -34,7 +29,6 @@ public void IterationSetup() Name = $"Entity{i}", Price = (decimal)(i * 0.1), Identifier = Guid.NewGuid(), - StringEnumValue = (StringEnum)(i % 2), NumericEnumValue = (NumericEnum)(i % 2), }).ToList(); @@ -46,6 +40,7 @@ protected LibComparator() { DbContainer = GetDbContainer(); DbContainer?.StartAsync().GetAwaiter().GetResult(); + LinqToDBForEFTools.Initialize(); } protected abstract void ConfigureDbContext(); @@ -96,6 +91,12 @@ public void RawInsert() } } + [Benchmark] + public async Task Linq2Db() + { + await DbContext.BulkCopyAsync(data); + } + [Benchmark] public async Task Z_EntityFramework_Extensions_EFCore() { @@ -134,196 +135,4 @@ public async Task EFCore_SaveChanges() DbContext.AddRange(data); await DbContext.SaveChangesAsync(); } - - private void RawInsertPostgreSql() - { - using var connection = (NpgsqlConnection)DbContext.Database.GetDbConnection(); - if (connection.State != ConnectionState.Open) - { - connection.Open(); - } - - const string copyCommand = $""" - COPY "{nameof(TestEntity)}" ( - "Name", - "Price", - "Identifier", - "CreatedAt", - "UpdatedAt", - "StringEnumValue", - "NumericEnumValue" - ) FROM STDIN (FORMAT BINARY) - """; - - using var writer = connection.BeginBinaryImport(copyCommand); - foreach (var entity in data) - { - writer.StartRow(); - writer.Write(entity.Name); - writer.Write(entity.Price); - writer.Write(entity.Identifier); - writer.Write(entity.CreatedAt); - writer.Write(entity.UpdatedAt); - writer.Write(entity.StringEnumValue.ToString()); - writer.Write((int)entity.NumericEnumValue); - } - - writer.Complete(); - } - - private void RawInsertSqlite() - { - var connection = (SqliteConnection)DbContext.Database.GetDbConnection(); - if (connection.State != ConnectionState.Open) - { - connection.Open(); - } - using var transaction = connection.BeginTransaction(); - using var command = connection.CreateCommand(); - command.CommandText = $""" - INSERT INTO "{nameof(TestEntity)}" ( - "Name", - "Price", - "Identifier", - "CreatedAt", - "UpdatedAt", - "StringEnumValue", - "NumericEnumValue" - ) VALUES (@Name, @Price, @Identifier, @CreatedAt, @UpdatedAt, @StringEnumValue, @NumericEnumValue) - """; - - command.Parameters.Add(new SqliteParameter("@Name", DbType.String)); - command.Parameters.Add(new SqliteParameter("@Price", DbType.Decimal)); - command.Parameters.Add(new SqliteParameter("@Identifier", DbType.Guid)); - command.Parameters.Add(new SqliteParameter("@CreatedAt", DbType.DateTime)); - command.Parameters.Add(new SqliteParameter("@UpdatedAt", DbType.DateTime2)); - command.Parameters.Add(new SqliteParameter("@StringEnumValue", DbType.String)); - command.Parameters.Add(new SqliteParameter("@NumericEnumValue", DbType.Int32)); - - foreach (var entity in data) - { - command.Parameters["@Name"].Value = entity.Name; - command.Parameters["@Price"].Value = entity.Price; - command.Parameters["@Identifier"].Value = entity.Identifier; - command.Parameters["@CreatedAt"].Value = entity.CreatedAt; - command.Parameters["@UpdatedAt"].Value = entity.UpdatedAt; - command.Parameters["@StringEnumValue"].Value = entity.StringEnumValue.ToString(); - command.Parameters["@NumericEnumValue"].Value = (int)entity.NumericEnumValue; - - command.ExecuteNonQuery(); - } - - transaction.Commit(); - } - - private void RawInsertSqlServer() - { - var connection = (SqlConnection)DbContext.Database.GetDbConnection(); - if (connection.State != ConnectionState.Open) - { - connection.Open(); - } - - using var bulkCopy = new SqlBulkCopy(connection); - - bulkCopy.DestinationTableName = nameof(TestEntity); - bulkCopy.BatchSize = 50_000; - bulkCopy.BulkCopyTimeout = 60; - - bulkCopy.ColumnMappings.Add("Name", "Name"); - bulkCopy.ColumnMappings.Add("Price", "Price"); - bulkCopy.ColumnMappings.Add("Identifier", "Identifier"); - bulkCopy.ColumnMappings.Add("CreatedAt", "CreatedAt"); - bulkCopy.ColumnMappings.Add("UpdatedAt", "UpdatedAt"); - bulkCopy.ColumnMappings.Add("StringEnumValue", "StringEnumValue"); - bulkCopy.ColumnMappings.Add("NumericEnumValue", "NumericEnumValue"); - - var dataTable = new DataTable(); - dataTable.Columns.Add("Name", typeof(string)); - dataTable.Columns.Add("Price", typeof(decimal)); - dataTable.Columns.Add("Identifier", typeof(Guid)); - dataTable.Columns.Add("CreatedAt", typeof(DateTime)); - dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset)); - dataTable.Columns.Add("StringEnumValue", typeof(string)); - dataTable.Columns.Add("NumericEnumValue", typeof(int)); - - foreach (var entity in data) - { - var row = dataTable.NewRow(); - row["Name"] = entity.Name; - row["Price"] = entity.Price; - row["Identifier"] = entity.Identifier; - row["CreatedAt"] = entity.CreatedAt; - row["UpdatedAt"] = entity.UpdatedAt; - row["StringEnumValue"] = entity.StringEnumValue.ToString(); - row["NumericEnumValue"] = (int)entity.NumericEnumValue; - dataTable.Rows.Add(row); - - if (dataTable.Rows.Count >= 50_000) - { - bulkCopy.WriteToServer(dataTable); - dataTable.Clear(); - } - } - - if (dataTable.Rows.Count > 0) - { - bulkCopy.WriteToServer(dataTable); - } - } - - private void RawInsertMySql() - { - var connection = (MySqlConnection)DbContext.Database.GetDbConnection(); - if (connection.State != ConnectionState.Open) - { - connection.Open(); - } - - var bulkCopy = new MySqlBulkCopy(connection); - - bulkCopy.DestinationTableName = nameof(TestEntity); - bulkCopy.BulkCopyTimeout = 60; - - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(0, "Name")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(1, "Price")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(2, "Identifier")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(3, "CreatedAt")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(4, "UpdatedAt")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(5, "StringEnumValue")); - bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(6, "NumericEnumValue")); - - var dataTable = new DataTable(); - dataTable.Columns.Add("Name", typeof(string)); - dataTable.Columns.Add("Price", typeof(decimal)); - dataTable.Columns.Add("Identifier", typeof(Guid)); - dataTable.Columns.Add("CreatedAt", typeof(DateTime)); - dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset)); - dataTable.Columns.Add("StringEnumValue", typeof(string)); - dataTable.Columns.Add("NumericEnumValue", typeof(int)); - - foreach (var entity in data) - { - var row = dataTable.NewRow(); - row["Name"] = entity.Name; - row["Price"] = entity.Price; - row["Identifier"] = entity.Identifier; - row["CreatedAt"] = entity.CreatedAt; - row["UpdatedAt"] = entity.UpdatedAt; - row["StringEnumValue"] = entity.StringEnumValue.ToString(); - row["NumericEnumValue"] = (int)entity.NumericEnumValue; - dataTable.Rows.Add(row); - - if (dataTable.Rows.Count >= 50_000) - { - bulkCopy.WriteToServer(dataTable); - dataTable.Clear(); - } - } - - if (dataTable.Rows.Count > 0) - { - bulkCopy.WriteToServer(dataTable); - } - } } diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/PhenX.EntityFrameworkCore.BulkInsert.Benchmark.csproj b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/PhenX.EntityFrameworkCore.BulkInsert.Benchmark.csproj index 1b2326d..8528f4f 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/PhenX.EntityFrameworkCore.BulkInsert.Benchmark.csproj +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/PhenX.EntityFrameworkCore.BulkInsert.Benchmark.csproj @@ -16,11 +16,13 @@ + + diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Program.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Program.cs index 00eeb73..60b844f 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Program.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Program.cs @@ -1,6 +1,8 @@ using BenchmarkDotNet.Configs; using BenchmarkDotNet.Running; +using PhenX.EntityFrameworkCore.BulkInsert.Benchmark.Providers; + namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; public class Program @@ -11,9 +13,14 @@ public static void Main(string[] args) .Create(DefaultConfig.Instance) .WithOptions(ConfigOptions.DisableOptimizationsValidator); - BenchmarkRunner.Run(config); - BenchmarkRunner.Run(config); - BenchmarkRunner.Run(config); - BenchmarkRunner.Run(config); + var comparators = new[] + { + typeof(LibComparatorMySql), + typeof(LibComparatorPostgreSql), + typeof(LibComparatorSqlite), + typeof(LibComparatorSqlServer), + }; + + BenchmarkRunner.Run(comparators, config); } } diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorMySql.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorMySql.cs similarity index 73% rename from tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorMySql.cs rename to tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorMySql.cs index e39fa78..9504eb5 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorMySql.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorMySql.cs @@ -1,6 +1,3 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Engines; - using DotNet.Testcontainers.Containers; using Microsoft.EntityFrameworkCore; @@ -9,11 +6,8 @@ using Testcontainers.MySql; -namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; +namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark.Providers; -[MinColumn, MaxColumn, BaselineColumn] -[MemoryDiagnoser] -[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)] public class LibComparatorMySql : LibComparator { protected override void ConfigureDbContext() diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorPostgreSql.cs similarity index 74% rename from tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs rename to tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorPostgreSql.cs index 0228703..3bb3595 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorPostgreSql.cs @@ -1,19 +1,15 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Engines; - using DotNet.Testcontainers.Containers; +using LinqToDB.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore; using PhenX.EntityFrameworkCore.BulkInsert.PostgreSql; using Testcontainers.PostgreSql; -namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; +namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark.Providers; -[MinColumn, MaxColumn, BaselineColumn] -[MemoryDiagnoser] -[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)] public class LibComparatorPostgreSql : LibComparator { protected override void ConfigureDbContext() @@ -23,6 +19,7 @@ protected override void ConfigureDbContext() DbContext = new TestDbContext(p => p .UseNpgsql(connectionString) .UseBulkInsertPostgreSql() + .UseLinqToDB() ); } diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorSqlServer.cs similarity index 68% rename from tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs rename to tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorSqlServer.cs index 508fc70..8db3e14 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorSqlServer.cs @@ -1,19 +1,15 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Engines; - using DotNet.Testcontainers.Containers; +using LinqToDB.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore; using PhenX.EntityFrameworkCore.BulkInsert.SqlServer; using Testcontainers.MsSql; -namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; +namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark.Providers; -[MinColumn, MaxColumn, BaselineColumn] -[MemoryDiagnoser] -[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)] public class LibComparatorSqlServer : LibComparator { protected override void ConfigureDbContext() @@ -23,6 +19,7 @@ protected override void ConfigureDbContext() DbContext = new TestDbContext(p => p .UseSqlServer(connectionString) .UseBulkInsertSqlServer() + .UseLinqToDB() ); } diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorSqlite.cs similarity index 69% rename from tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs rename to tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorSqlite.cs index 3541adc..055375b 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/Providers/LibComparatorSqlite.cs @@ -1,17 +1,13 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Engines; - using DotNet.Testcontainers.Containers; +using LinqToDB.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore; using PhenX.EntityFrameworkCore.BulkInsert.Sqlite; -namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark; +namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark.Providers; -[MinColumn, MaxColumn, BaselineColumn] -[MemoryDiagnoser] -[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)] public class LibComparatorSqlite : LibComparator { protected override void ConfigureDbContext() @@ -21,6 +17,7 @@ protected override void ConfigureDbContext() DbContext = new TestDbContext(p => p .UseSqlite(connectionString) .UseBulkInsertSqlite() + .UseLinqToDB() ); } diff --git a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/TestEntity.cs b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/TestEntity.cs index d9fc5ac..ef9ecd2 100644 --- a/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/TestEntity.cs +++ b/tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/TestEntity.cs @@ -16,9 +16,6 @@ public class TestEntity public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow; - [Column(nameof(StringEnumValue), TypeName = "text")] - public StringEnum StringEnumValue { get; set; } - public NumericEnum NumericEnumValue { get; set; } } @@ -27,9 +24,3 @@ public enum NumericEnum First = 1, Second = 2, } - -public enum StringEnum -{ - First, - Second, -}