Skip to content

Commit 3502eae

Browse files
authored
Merge pull request #25295 from abpframework/fix/ef-core-database-provider-detection
Detect EF Core database provider by keyword match
2 parents 2e50517 + 7819e60 commit 3502eae

4 files changed

Lines changed: 170 additions & 23 deletions

File tree

framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -197,29 +197,7 @@ protected virtual void TrySetDatabaseProvider(ModelBuilder modelBuilder)
197197

198198
protected virtual EfCoreDatabaseProvider? GetDatabaseProviderOrNull(ModelBuilder modelBuilder)
199199
{
200-
switch (Database.ProviderName)
201-
{
202-
case "Microsoft.EntityFrameworkCore.SqlServer":
203-
return EfCoreDatabaseProvider.SqlServer;
204-
case "Npgsql.EntityFrameworkCore.PostgreSQL":
205-
return EfCoreDatabaseProvider.PostgreSql;
206-
case "Pomelo.EntityFrameworkCore.MySql":
207-
case "MySql.Data.MySqlClient":
208-
return EfCoreDatabaseProvider.MySql;
209-
case "Oracle.EntityFrameworkCore":
210-
case "Devart.Data.Oracle.Entity.EFCore":
211-
return EfCoreDatabaseProvider.Oracle;
212-
case "Microsoft.EntityFrameworkCore.Sqlite":
213-
return EfCoreDatabaseProvider.Sqlite;
214-
case "Microsoft.EntityFrameworkCore.InMemory":
215-
return EfCoreDatabaseProvider.InMemory;
216-
case "FirebirdSql.EntityFrameworkCore.Firebird":
217-
return EfCoreDatabaseProvider.Firebird;
218-
case "Microsoft.EntityFrameworkCore.Cosmos":
219-
return EfCoreDatabaseProvider.Cosmos;
220-
default:
221-
return null;
222-
}
200+
return EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(Database.ProviderName);
223201
}
224202

225203
public async override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using System;
2+
3+
namespace Volo.Abp.EntityFrameworkCore;
4+
5+
public static class EfCoreDatabaseProviderHelper
6+
{
7+
public static EfCoreDatabaseProvider? GetDatabaseProviderOrNull(string? providerName)
8+
{
9+
if (providerName.IsNullOrWhiteSpace())
10+
{
11+
return null;
12+
}
13+
14+
if (providerName.Contains("SqlServer", StringComparison.OrdinalIgnoreCase))
15+
{
16+
return EfCoreDatabaseProvider.SqlServer;
17+
}
18+
if (providerName.Contains("Npgsql", StringComparison.OrdinalIgnoreCase) ||
19+
providerName.Contains("PostgreSQL", StringComparison.OrdinalIgnoreCase))
20+
{
21+
return EfCoreDatabaseProvider.PostgreSql;
22+
}
23+
if (providerName.Contains("MySql", StringComparison.OrdinalIgnoreCase) ||
24+
providerName.Contains("Pomelo", StringComparison.OrdinalIgnoreCase))
25+
{
26+
return EfCoreDatabaseProvider.MySql;
27+
}
28+
if (providerName.Contains("Oracle", StringComparison.OrdinalIgnoreCase) ||
29+
providerName.Contains("Devart", StringComparison.OrdinalIgnoreCase))
30+
{
31+
return EfCoreDatabaseProvider.Oracle;
32+
}
33+
if (providerName.Contains("Sqlite", StringComparison.OrdinalIgnoreCase))
34+
{
35+
return EfCoreDatabaseProvider.Sqlite;
36+
}
37+
if (providerName.Contains("InMemory", StringComparison.OrdinalIgnoreCase))
38+
{
39+
return EfCoreDatabaseProvider.InMemory;
40+
}
41+
if (providerName.Contains("Firebird", StringComparison.OrdinalIgnoreCase))
42+
{
43+
return EfCoreDatabaseProvider.Firebird;
44+
}
45+
if (providerName.Contains("Cosmos", StringComparison.OrdinalIgnoreCase))
46+
{
47+
return EfCoreDatabaseProvider.Cosmos;
48+
}
49+
50+
return null;
51+
}
52+
}

framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo.Abp.EntityFrameworkCore.Tests.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@
1717

1818
<ItemGroup>
1919
<PackageReference Include="Microsoft.NET.Test.Sdk" />
20+
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" />
21+
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
22+
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
23+
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" />
24+
<PackageReference Include="MySql.EntityFrameworkCore" />
25+
<PackageReference Include="Oracle.EntityFrameworkCore" />
2026
</ItemGroup>
2127

2228
</Project>
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using Shouldly;
3+
using Xunit;
4+
5+
namespace Volo.Abp.EntityFrameworkCore;
6+
7+
public class EfCoreDatabaseProviderHelper_Tests
8+
{
9+
[Fact]
10+
public void Should_Detect_SqlServer_From_Real_Assembly()
11+
{
12+
var builder = new DbContextOptionsBuilder<EmptyDbContext>();
13+
Microsoft.EntityFrameworkCore.SqlServerDbContextOptionsExtensions.UseSqlServer(builder, "Server=localhost;Database=test");
14+
using var context = new EmptyDbContext(builder.Options);
15+
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(context.Database.ProviderName)
16+
.ShouldBe(EfCoreDatabaseProvider.SqlServer);
17+
}
18+
19+
[Fact]
20+
public void Should_Detect_PostgreSql_From_Real_Assembly()
21+
{
22+
var builder = new DbContextOptionsBuilder<EmptyDbContext>();
23+
Microsoft.EntityFrameworkCore.NpgsqlDbContextOptionsBuilderExtensions.UseNpgsql(builder, "Host=localhost;Database=test");
24+
using var context = new EmptyDbContext(builder.Options);
25+
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(context.Database.ProviderName)
26+
.ShouldBe(EfCoreDatabaseProvider.PostgreSql);
27+
}
28+
29+
[Fact]
30+
public void Should_Detect_MySql_Pomelo_From_Assembly_Name()
31+
{
32+
var providerName = typeof(Microsoft.EntityFrameworkCore.MySqlDbContextOptionsBuilderExtensions).Assembly.GetName().Name;
33+
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(providerName)
34+
.ShouldBe(EfCoreDatabaseProvider.MySql);
35+
}
36+
37+
[Fact]
38+
public void Should_Detect_MySql_Oracle_From_Real_Assembly()
39+
{
40+
var builder = new DbContextOptionsBuilder<EmptyDbContext>();
41+
Microsoft.EntityFrameworkCore.MySQLDbContextOptionsExtensions.UseMySQL(builder, "Server=localhost;Database=test");
42+
using var context = new EmptyDbContext(builder.Options);
43+
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(context.Database.ProviderName)
44+
.ShouldBe(EfCoreDatabaseProvider.MySql);
45+
}
46+
47+
[Fact]
48+
public void Should_Detect_Oracle_From_Real_Assembly()
49+
{
50+
var builder = new DbContextOptionsBuilder<EmptyDbContext>();
51+
Microsoft.EntityFrameworkCore.OracleDbContextOptionsExtensions.UseOracle(builder, "Data Source=localhost/XE");
52+
using var context = new EmptyDbContext(builder.Options);
53+
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(context.Database.ProviderName)
54+
.ShouldBe(EfCoreDatabaseProvider.Oracle);
55+
}
56+
57+
[Fact]
58+
public void Should_Detect_Sqlite_From_Real_Assembly()
59+
{
60+
var builder = new DbContextOptionsBuilder<EmptyDbContext>();
61+
Microsoft.EntityFrameworkCore.SqliteDbContextOptionsBuilderExtensions.UseSqlite(builder, "Data Source=:memory:");
62+
using var context = new EmptyDbContext(builder.Options);
63+
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(context.Database.ProviderName)
64+
.ShouldBe(EfCoreDatabaseProvider.Sqlite);
65+
}
66+
67+
[Fact]
68+
public void Should_Detect_InMemory_From_Real_Assembly()
69+
{
70+
var builder = new DbContextOptionsBuilder<EmptyDbContext>();
71+
Microsoft.EntityFrameworkCore.InMemoryDbContextOptionsExtensions.UseInMemoryDatabase(builder, "test");
72+
using var context = new EmptyDbContext(builder.Options);
73+
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(context.Database.ProviderName)
74+
.ShouldBe(EfCoreDatabaseProvider.InMemory);
75+
}
76+
77+
[Theory]
78+
[InlineData("Devart.Data.Oracle.Entity.EFCore", EfCoreDatabaseProvider.Oracle)]
79+
[InlineData("FirebirdSql.EntityFrameworkCore.Firebird", EfCoreDatabaseProvider.Firebird)]
80+
[InlineData("Microsoft.EntityFrameworkCore.Cosmos", EfCoreDatabaseProvider.Cosmos)]
81+
public void Should_Detect_Providers_Without_Package_Reference(string providerName, EfCoreDatabaseProvider expected)
82+
{
83+
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(providerName).ShouldBe(expected);
84+
}
85+
86+
[Theory]
87+
[InlineData("microsoft.entityframeworkcore.sqlserver", EfCoreDatabaseProvider.SqlServer)]
88+
[InlineData("POMELO.ENTITYFRAMEWORKCORE.MYSQL", EfCoreDatabaseProvider.MySql)]
89+
[InlineData("npgsql.entityframeworkcore.postgresql", EfCoreDatabaseProvider.PostgreSql)]
90+
public void Should_Detect_Providers_Case_Insensitively(string providerName, EfCoreDatabaseProvider expected)
91+
{
92+
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(providerName).ShouldBe(expected);
93+
}
94+
95+
[Theory]
96+
[InlineData(null)]
97+
[InlineData("")]
98+
[InlineData(" ")]
99+
[InlineData("Some.Unknown.Provider")]
100+
public void Should_Return_Null_For_Unknown_Or_Empty(string? providerName)
101+
{
102+
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(providerName).ShouldBeNull();
103+
}
104+
105+
private class EmptyDbContext : DbContext
106+
{
107+
public EmptyDbContext(DbContextOptions<EmptyDbContext> options) : base(options)
108+
{
109+
}
110+
}
111+
}

0 commit comments

Comments
 (0)