Skip to content

Commit 0ba0264

Browse files
committed
Do not insert NumericEnumValue because of linq2db not handling it right with provider specific import and simplify benchmark
1 parent 8891199 commit 0ba0264

7 files changed

Lines changed: 69 additions & 111 deletions

File tree

tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.RawInsert.cs

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
using Microsoft.Data.Sqlite;
55
using Microsoft.EntityFrameworkCore;
66

7+
using MySqlConnector;
8+
79
using Npgsql;
810

911
namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark;
@@ -25,8 +27,7 @@ private void RawInsertPostgreSql()
2527
"Identifier",
2628
"CreatedAt",
2729
"UpdatedAt",
28-
"StringEnumValue",
29-
"NumericEnumValue"
30+
"StringEnumValue"
3031
) FROM STDIN (FORMAT BINARY)
3132
""";
3233

@@ -40,7 +41,6 @@ private void RawInsertPostgreSql()
4041
writer.Write(entity.CreatedAt);
4142
writer.Write(entity.UpdatedAt);
4243
writer.Write(entity.StringEnumValue.ToString());
43-
writer.Write((int)entity.NumericEnumValue);
4444
}
4545

4646
writer.Complete();
@@ -63,9 +63,8 @@ private void RawInsertSqlite()
6363
"Identifier",
6464
"CreatedAt",
6565
"UpdatedAt",
66-
"StringEnumValue",
67-
"NumericEnumValue"
68-
) VALUES (@Name, @Price, @Identifier, @CreatedAt, @UpdatedAt, @StringEnumValue, @NumericEnumValue)
66+
"StringEnumValue"
67+
) VALUES (@Name, @Price, @Identifier, @CreatedAt, @UpdatedAt, @StringEnumValue)
6968
""";
7069

7170
command.Parameters.Add(new SqliteParameter("@Name", DbType.String));
@@ -74,7 +73,6 @@ private void RawInsertSqlite()
7473
command.Parameters.Add(new SqliteParameter("@CreatedAt", DbType.DateTime));
7574
command.Parameters.Add(new SqliteParameter("@UpdatedAt", DbType.DateTime2));
7675
command.Parameters.Add(new SqliteParameter("@StringEnumValue", DbType.String));
77-
command.Parameters.Add(new SqliteParameter("@NumericEnumValue", DbType.Int32));
7876

7977
foreach (var entity in data)
8078
{
@@ -84,7 +82,6 @@ private void RawInsertSqlite()
8482
command.Parameters["@CreatedAt"].Value = entity.CreatedAt;
8583
command.Parameters["@UpdatedAt"].Value = entity.UpdatedAt;
8684
command.Parameters["@StringEnumValue"].Value = entity.StringEnumValue.ToString();
87-
command.Parameters["@NumericEnumValue"].Value = (int)entity.NumericEnumValue;
8885

8986
command.ExecuteNonQuery();
9087
}
@@ -112,7 +109,6 @@ private void RawInsertSqlServer()
112109
bulkCopy.ColumnMappings.Add("CreatedAt", "CreatedAt");
113110
bulkCopy.ColumnMappings.Add("UpdatedAt", "UpdatedAt");
114111
bulkCopy.ColumnMappings.Add("StringEnumValue", "StringEnumValue");
115-
bulkCopy.ColumnMappings.Add("NumericEnumValue", "NumericEnumValue");
116112

117113
var dataTable = new DataTable();
118114
dataTable.Columns.Add("Name", typeof(string));
@@ -121,7 +117,6 @@ private void RawInsertSqlServer()
121117
dataTable.Columns.Add("CreatedAt", typeof(DateTime));
122118
dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset));
123119
dataTable.Columns.Add("StringEnumValue", typeof(string));
124-
dataTable.Columns.Add("NumericEnumValue", typeof(int));
125120

126121
foreach (var entity in data)
127122
{
@@ -132,7 +127,58 @@ private void RawInsertSqlServer()
132127
row["CreatedAt"] = entity.CreatedAt;
133128
row["UpdatedAt"] = entity.UpdatedAt;
134129
row["StringEnumValue"] = entity.StringEnumValue.ToString();
135-
row["NumericEnumValue"] = (int)entity.NumericEnumValue;
130+
dataTable.Rows.Add(row);
131+
132+
if (dataTable.Rows.Count >= 50_000)
133+
{
134+
bulkCopy.WriteToServer(dataTable);
135+
dataTable.Clear();
136+
}
137+
}
138+
139+
if (dataTable.Rows.Count > 0)
140+
{
141+
bulkCopy.WriteToServer(dataTable);
142+
}
143+
}
144+
145+
private void RawInsertMySql()
146+
{
147+
var connection = (MySqlConnection)DbContext.Database.GetDbConnection();
148+
if (connection.State != ConnectionState.Open)
149+
{
150+
connection.Open();
151+
}
152+
153+
var bulkCopy = new MySqlBulkCopy(connection);
154+
155+
bulkCopy.DestinationTableName = nameof(TestEntity);
156+
bulkCopy.BulkCopyTimeout = 60;
157+
158+
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(0, "Name"));
159+
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(1, "Price"));
160+
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(2, "Identifier"));
161+
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(3, "CreatedAt"));
162+
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(4, "UpdatedAt"));
163+
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(5, "StringEnumValue"));
164+
165+
var dataTable = new DataTable();
166+
dataTable.Columns.Add("Name", typeof(string));
167+
dataTable.Columns.Add("Price", typeof(decimal));
168+
dataTable.Columns.Add("Identifier", typeof(Guid));
169+
dataTable.Columns.Add("CreatedAt", typeof(DateTime));
170+
dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset));
171+
dataTable.Columns.Add("StringEnumValue", typeof(string));
172+
173+
foreach (var entity in data)
174+
{
175+
var row = dataTable.NewRow();
176+
row["Name"] = entity.Name;
177+
row["Price"] = entity.Price;
178+
row["Identifier"] = entity.Identifier;
179+
row["CreatedAt"] = entity.CreatedAt;
180+
row["UpdatedAt"] = entity.UpdatedAt;
181+
row["StringEnumValue"] = entity.StringEnumValue.ToString();
136182
dataTable.Rows.Add(row);
137183

138184
if (dataTable.Rows.Count >= 50_000)

tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparator.cs

Lines changed: 12 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
11
using BenchmarkDotNet.Attributes;
2+
using BenchmarkDotNet.Engines;
23

34
using DotNet.Testcontainers.Containers;
45

56
using EFCore.BulkExtensions;
67

8+
using LinqToDB.Data;
79
using LinqToDB.EntityFrameworkCore;
810

9-
using Microsoft.Data.SqlClient;
10-
using Microsoft.Data.Sqlite;
11-
using Microsoft.EntityFrameworkCore;
12-
13-
using MySqlConnector;
14-
15-
using Npgsql;
16-
1711
using PhenX.EntityFrameworkCore.BulkInsert.Extensions;
1812

1913
namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark;
2014

15+
[MemoryDiagnoser]
16+
[SimpleJob(RunStrategy.ColdStart, launchCount: 1, warmupCount: 0, iterationCount: 5)]
2117
public abstract partial class LibComparator
2218
{
2319
[Params(500_000/*, 1_000_000/*, 10_000_000*/)]
@@ -35,7 +31,6 @@ public void IterationSetup()
3531
Price = (decimal)(i * 0.1),
3632
Identifier = Guid.NewGuid(),
3733
StringEnumValue = (StringEnum)(i % 2),
38-
NumericEnumValue = (NumericEnum)(i % 2),
3934
}).ToList();
4035

4136
ConfigureDbContext();
@@ -100,7 +95,10 @@ public void RawInsert()
10095
[Benchmark]
10196
public async Task Linq2Db()
10297
{
103-
await DbContext.BulkCopyAsync(data);
98+
await DbContext.BulkCopyAsync(new BulkCopyOptions
99+
{
100+
BulkCopyType = BulkCopyType.ProviderSpecific,
101+
}, data);
104102
}
105103

106104
[Benchmark]
@@ -135,65 +133,10 @@ await DbContext.BulkInsertAsync(data, options =>
135133
// });
136134
// }
137135

138-
// [Benchmark]
139-
// public async Task EFCore_SaveChanges()
140-
// {
141-
// DbContext.AddRange(data);
142-
// await DbContext.SaveChangesAsync();
143-
// }
144-
145-
private void RawInsertMySql()
136+
[Benchmark]
137+
public async Task EFCore_SaveChanges()
146138
{
147-
var connection = (MySqlConnection)DbContext.Database.GetDbConnection();
148-
if (connection.State != ConnectionState.Open)
149-
{
150-
connection.Open();
151-
}
152-
153-
var bulkCopy = new MySqlBulkCopy(connection);
154-
155-
bulkCopy.DestinationTableName = nameof(TestEntity);
156-
bulkCopy.BulkCopyTimeout = 60;
157-
158-
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(0, "Name"));
159-
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(1, "Price"));
160-
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(2, "Identifier"));
161-
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(3, "CreatedAt"));
162-
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(4, "UpdatedAt"));
163-
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(5, "StringEnumValue"));
164-
bulkCopy.ColumnMappings.Add(new MySqlBulkCopyColumnMapping(6, "NumericEnumValue"));
165-
166-
var dataTable = new DataTable();
167-
dataTable.Columns.Add("Name", typeof(string));
168-
dataTable.Columns.Add("Price", typeof(decimal));
169-
dataTable.Columns.Add("Identifier", typeof(Guid));
170-
dataTable.Columns.Add("CreatedAt", typeof(DateTime));
171-
dataTable.Columns.Add("UpdatedAt", typeof(DateTimeOffset));
172-
dataTable.Columns.Add("StringEnumValue", typeof(string));
173-
dataTable.Columns.Add("NumericEnumValue", typeof(int));
174-
175-
foreach (var entity in data)
176-
{
177-
var row = dataTable.NewRow();
178-
row["Name"] = entity.Name;
179-
row["Price"] = entity.Price;
180-
row["Identifier"] = entity.Identifier;
181-
row["CreatedAt"] = entity.CreatedAt;
182-
row["UpdatedAt"] = entity.UpdatedAt;
183-
row["StringEnumValue"] = entity.StringEnumValue.ToString();
184-
row["NumericEnumValue"] = (int)entity.NumericEnumValue;
185-
dataTable.Rows.Add(row);
186-
187-
if (dataTable.Rows.Count >= 50_000)
188-
{
189-
bulkCopy.WriteToServer(dataTable);
190-
dataTable.Clear();
191-
}
192-
}
193-
194-
if (dataTable.Rows.Count > 0)
195-
{
196-
bulkCopy.WriteToServer(dataTable);
197-
}
139+
DbContext.AddRange(data);
140+
await DbContext.SaveChangesAsync();
198141
}
199142
}

tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorMySql.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
using BenchmarkDotNet.Attributes;
2-
using BenchmarkDotNet.Engines;
3-
41
using DotNet.Testcontainers.Containers;
52

63
using Microsoft.EntityFrameworkCore;
@@ -11,9 +8,6 @@
118

129
namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark;
1310

14-
[MinColumn, MaxColumn, BaselineColumn]
15-
[MemoryDiagnoser]
16-
[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)]
1711
public class LibComparatorMySql : LibComparator
1812
{
1913
protected override void ConfigureDbContext()

tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorPostgreSql.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
using BenchmarkDotNet.Attributes;
2-
using BenchmarkDotNet.Engines;
3-
41
using DotNet.Testcontainers.Containers;
52

63
using LinqToDB.EntityFrameworkCore;
@@ -13,8 +10,6 @@
1310

1411
namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark;
1512

16-
[MemoryDiagnoser]
17-
[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)]
1813
public class LibComparatorPostgreSql : LibComparator
1914
{
2015
protected override void ConfigureDbContext()

tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlServer.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
using BenchmarkDotNet.Attributes;
2-
using BenchmarkDotNet.Engines;
3-
41
using DotNet.Testcontainers.Containers;
52

63
using LinqToDB.EntityFrameworkCore;
@@ -13,9 +10,6 @@
1310

1411
namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark;
1512

16-
[MinColumn, MaxColumn, BaselineColumn]
17-
[MemoryDiagnoser]
18-
[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)]
1913
public class LibComparatorSqlServer : LibComparator
2014
{
2115
protected override void ConfigureDbContext()

tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/LibComparatorSqlite.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
using BenchmarkDotNet.Attributes;
2-
using BenchmarkDotNet.Engines;
3-
41
using DotNet.Testcontainers.Containers;
52

63
using LinqToDB.EntityFrameworkCore;
@@ -11,9 +8,6 @@
118

129
namespace PhenX.EntityFrameworkCore.BulkInsert.Benchmark;
1310

14-
[MinColumn, MaxColumn, BaselineColumn]
15-
[MemoryDiagnoser]
16-
[SimpleJob(RunStrategy.Throughput, launchCount: 1, warmupCount: 0, iterationCount: 5)]
1711
public class LibComparatorSqlite : LibComparator
1812
{
1913
protected override void ConfigureDbContext()

tests/PhenX.EntityFrameworkCore.BulkInsert.Benchmark/TestEntity.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,6 @@ public class TestEntity
1818

1919
[Column(nameof(StringEnumValue), TypeName = "text")]
2020
public StringEnum StringEnumValue { get; set; }
21-
22-
public NumericEnum NumericEnumValue { get; set; }
23-
}
24-
25-
public enum NumericEnum
26-
{
27-
First = 1,
28-
Second = 2,
2921
}
3022

3123
public enum StringEnum

0 commit comments

Comments
 (0)