Skip to content

Commit e0bd7b3

Browse files
committed
VCST-1752: Fix performance degradation on SQL Server (#2834)
1 parent 885c8fe commit e0bd7b3

14 files changed

+120
-68
lines changed

src/VirtoCommerce.Platform.Data.MySql/DbContextOptionsBuilderExtensions.cs

-15
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using Microsoft.EntityFrameworkCore.Infrastructure;
3+
using Microsoft.Extensions.Configuration;
4+
5+
namespace VirtoCommerce.Platform.Data.MySql.Extensions;
6+
7+
public static class DbContextOptionsBuilderExtensions
8+
{
9+
/// <summary>
10+
/// Configures the context to use MySql.
11+
/// </summary>
12+
public static DbContextOptionsBuilder UseMySqlDatabase(
13+
this DbContextOptionsBuilder optionsBuilder,
14+
string? connectionString,
15+
Type migrationsAssemblyMarkerType,
16+
IConfiguration configuration,
17+
Action<MySqlDbContextOptionsBuilder, IConfiguration>? mySqlOptionsAction = null)
18+
{
19+
return optionsBuilder.UseMySql(connectionString,
20+
ServerVersion.AutoDetect(connectionString),
21+
mySqlDbContextOptionsBuilder =>
22+
{
23+
mySqlDbContextOptionsBuilder.MigrationsAssembly(migrationsAssemblyMarkerType.Assembly.GetName().Name);
24+
mySqlOptionsAction?.Invoke(mySqlDbContextOptionsBuilder, configuration);
25+
});
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace VirtoCommerce.Platform.Data.MySql;
2+
3+
public class MySqlDataAssemblyMarker
4+
{
5+
}

src/VirtoCommerce.Platform.Data.MySql/MySqlDbContextFactory.cs

+2-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
61
using Microsoft.EntityFrameworkCore;
72
using Microsoft.EntityFrameworkCore.Design;
83
using VirtoCommerce.Platform.Data.Repositories;
@@ -23,7 +18,7 @@ PlatformDbContext IDesignTimeDbContextFactory<PlatformDbContext>.CreateDbContext
2318
connectionString,
2419
ResolveServerVersion(serverVersion, connectionString),
2520
db => db
26-
.MigrationsAssembly(typeof(MySqlDbContextFactory).Assembly.GetName().Name));
21+
.MigrationsAssembly(typeof(MySqlDataAssemblyMarker).Assembly.GetName().Name));
2722

2823
return new PlatformDbContext(builder.Options);
2924
}
@@ -38,7 +33,7 @@ SecurityDbContext IDesignTimeDbContextFactory<SecurityDbContext>.CreateDbContext
3833
connectionString,
3934
ResolveServerVersion(serverVersion, connectionString),
4035
db => db
41-
.MigrationsAssembly(typeof(MySqlDbContextFactory).Assembly.GetName().Name));
36+
.MigrationsAssembly(typeof(MySqlDataAssemblyMarker).Assembly.GetName().Name));
4237

4338
builder.UseOpenIddict();
4439

src/VirtoCommerce.Platform.Data.PostgreSql/DbContextOptionsBuilderExtensions.cs

-14
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using Microsoft.Extensions.Configuration;
3+
using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure;
4+
5+
namespace VirtoCommerce.Platform.Data.PostgreSql.Extensions;
6+
7+
public static class DbContextOptionsBuilderExtensions
8+
{
9+
/// <summary>
10+
/// Configures the context to use PostgreSql.
11+
/// </summary>
12+
public static DbContextOptionsBuilder UsePostgreSqlDatabase(
13+
this DbContextOptionsBuilder optionsBuilder,
14+
string? connectionString,
15+
Type migrationsAssemblyMarkerType,
16+
IConfiguration configuration,
17+
Action<NpgsqlDbContextOptionsBuilder, IConfiguration>? npgsqlOptionsAction = null)
18+
{
19+
return optionsBuilder.UseNpgsql(connectionString,
20+
npgsqlDbContextOptionsBuilder =>
21+
{
22+
npgsqlDbContextOptionsBuilder.MigrationsAssembly(migrationsAssemblyMarkerType.Assembly.GetName().Name);
23+
npgsqlOptionsAction?.Invoke(npgsqlDbContextOptionsBuilder, configuration);
24+
});
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace VirtoCommerce.Platform.Data.PostgreSql;
2+
3+
public class PostgreSqlDataAssemblyMarker
4+
{
5+
}

src/VirtoCommerce.Platform.Data.PostgreSql/PostgreSqlDbContextFactory.cs

+2-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
61
using Microsoft.EntityFrameworkCore;
72
using Microsoft.EntityFrameworkCore.Design;
83
using VirtoCommerce.Platform.Data.Repositories;
@@ -20,7 +15,7 @@ PlatformDbContext IDesignTimeDbContextFactory<PlatformDbContext>.CreateDbContext
2015

2116
builder.UseNpgsql(
2217
connectionString,
23-
db => db.MigrationsAssembly(typeof(PostgreSqlDbContextFactory).Assembly.GetName().Name));
18+
db => db.MigrationsAssembly(typeof(PostgreSqlDataAssemblyMarker).Assembly.GetName().Name));
2419

2520
return new PlatformDbContext(builder.Options);
2621
}
@@ -32,7 +27,7 @@ SecurityDbContext IDesignTimeDbContextFactory<SecurityDbContext>.CreateDbContext
3227

3328
builder.UseNpgsql(
3429
connectionString,
35-
db => db.MigrationsAssembly(typeof(PostgreSqlDbContextFactory).Assembly.GetName().Name));
30+
db => db.MigrationsAssembly(typeof(PostgreSqlDataAssemblyMarker).Assembly.GetName().Name));
3631

3732
builder.UseOpenIddict();
3833

src/VirtoCommerce.Platform.Data.SqlServer/DbContextOptionsBuilderExtensions.cs

-16
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using Microsoft.EntityFrameworkCore.Infrastructure;
3+
using Microsoft.Extensions.Configuration;
4+
5+
namespace VirtoCommerce.Platform.Data.SqlServer.Extensions;
6+
7+
public static class DbContextOptionsBuilderExtensions
8+
{
9+
/// <summary>
10+
/// Configures the context to use SqlServer.
11+
/// </summary>
12+
public static DbContextOptionsBuilder UseSqlServerDatabase(
13+
this DbContextOptionsBuilder optionsBuilder,
14+
string? connectionString,
15+
Type migrationsAssemblyMarkerType,
16+
IConfiguration configuration,
17+
Action<SqlServerDbContextOptionsBuilder, IConfiguration>? sqlServerOptionsAction = null)
18+
{
19+
return optionsBuilder.UseSqlServer(connectionString,
20+
sqlServerOptionsBuilder =>
21+
{
22+
var compatibilityLevel = configuration.GetValue<int?>("SqlServer:CompatibilityLevel", null);
23+
if (compatibilityLevel != null)
24+
{
25+
sqlServerOptionsBuilder.UseCompatibilityLevel(compatibilityLevel.Value);
26+
}
27+
28+
sqlServerOptionsBuilder.MigrationsAssembly(migrationsAssemblyMarkerType.Assembly.GetName().Name);
29+
sqlServerOptionsAction?.Invoke(sqlServerOptionsBuilder, configuration);
30+
});
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace VirtoCommerce.Platform.Data.SqlServer;
2+
3+
public class SqlServerDataAssemblyMarker
4+
{
5+
}

src/VirtoCommerce.Platform.Data.SqlServer/SqlServerDbContextFactory.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ PlatformDbContext IDesignTimeDbContextFactory<PlatformDbContext>.CreateDbContext
1515

1616
builder.UseSqlServer(
1717
connectionString,
18-
db => db.MigrationsAssembly(typeof(SqlServerDbContextFactory).Assembly.GetName().Name));
18+
db => db.MigrationsAssembly(typeof(SqlServerDataAssemblyMarker).Assembly.GetName().Name));
1919

2020
return new PlatformDbContext(builder.Options);
2121
}
@@ -27,7 +27,7 @@ SecurityDbContext IDesignTimeDbContextFactory<SecurityDbContext>.CreateDbContext
2727

2828
builder.UseSqlServer(
2929
connectionString,
30-
db => db.MigrationsAssembly(typeof(SqlServerDbContextFactory).Assembly.GetName().Name));
30+
db => db.MigrationsAssembly(typeof(SqlServerDataAssemblyMarker).Assembly.GetName().Name));
3131

3232
builder.UseOpenIddict();
3333

src/VirtoCommerce.Platform.Web/Startup.cs

+9-7
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,14 @@
4646
using VirtoCommerce.Platform.Core.Settings;
4747
using VirtoCommerce.Platform.Data.Extensions;
4848
using VirtoCommerce.Platform.Data.MySql;
49+
using VirtoCommerce.Platform.Data.MySql.Extensions;
4950
using VirtoCommerce.Platform.Data.MySql.HealthCheck;
5051
using VirtoCommerce.Platform.Data.PostgreSql;
52+
using VirtoCommerce.Platform.Data.PostgreSql.Extensions;
5153
using VirtoCommerce.Platform.Data.PostgreSql.HealthCheck;
5254
using VirtoCommerce.Platform.Data.Repositories;
5355
using VirtoCommerce.Platform.Data.SqlServer;
56+
using VirtoCommerce.Platform.Data.SqlServer.Extensions;
5457
using VirtoCommerce.Platform.Data.SqlServer.HealthCheck;
5558
using VirtoCommerce.Platform.DistributedLock;
5659
using VirtoCommerce.Platform.Hangfire.Extensions;
@@ -135,19 +138,18 @@ public void ConfigureServices(IServiceCollection services)
135138

136139
services.AddDbContext<PlatformDbContext>((provider, options) =>
137140
{
138-
var databaseProvider = Configuration.GetValue("DatabaseProvider", "SqlServer");
139141
var connectionString = Configuration.GetConnectionString("VirtoCommerce");
140142

141143
switch (databaseProvider)
142144
{
143145
case "MySql":
144-
options.UseMySqlDatabase(connectionString);
146+
options.UseMySqlDatabase(connectionString, typeof(MySqlDataAssemblyMarker), Configuration);
145147
break;
146148
case "PostgreSql":
147-
options.UsePostgreSqlDatabase(connectionString);
149+
options.UsePostgreSqlDatabase(connectionString, typeof(PostgreSqlDataAssemblyMarker), Configuration);
148150
break;
149151
default:
150-
options.UseSqlServerDatabase(connectionString);
152+
options.UseSqlServerDatabase(connectionString, typeof(SqlServerDataAssemblyMarker), Configuration);
151153
break;
152154
}
153155
});
@@ -205,13 +207,13 @@ public void ConfigureServices(IServiceCollection services)
205207
switch (databaseProvider)
206208
{
207209
case "MySql":
208-
options.UseMySqlDatabase(connectionString);
210+
options.UseMySqlDatabase(connectionString, typeof(MySqlDataAssemblyMarker), Configuration);
209211
break;
210212
case "PostgreSql":
211-
options.UsePostgreSqlDatabase(connectionString);
213+
options.UsePostgreSqlDatabase(connectionString, typeof(PostgreSqlDataAssemblyMarker), Configuration);
212214
break;
213215
default:
214-
options.UseSqlServerDatabase(connectionString);
216+
options.UseSqlServerDatabase(connectionString, typeof(SqlServerDataAssemblyMarker), Configuration);
215217
break;
216218
}
217219

src/VirtoCommerce.Platform.Web/appsettings.json

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
"VirtoCommerce": "Data Source=(local);Initial Catalog=VirtoCommerce3.net8;Persist Security Info=True;User ID=virto;Password=virto;Connect Timeout=30;TrustServerCertificate=True;"
66
//"RedisConnectionString": "127.0.0.1:6379,ssl=False"
77
},
8+
"SqlServer": {
9+
// Set compatibility level to 120 (SQL Server 2014) to prevent the use of OPENJSON, which has poor performance.
10+
// https://github.com/dotnet/efcore/issues/32394
11+
// "CompatibilityLevel": 120
12+
},
813
"Serilog": {
914
"Using": [
1015
"Serilog.Sinks.Console",

0 commit comments

Comments
 (0)