Browse Source

Merge pull request #25297 from abpframework/auto-merge/rel-10-3/4510

Merge branch dev with rel-10.3
pull/25306/head
Volosoft Agent 2 weeks ago
committed by GitHub
parent
commit
441439fbe7
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 15
      docs/en/studio/release-notes.md
  2. 1
      docs/en/studio/version-mapping.md
  3. 24
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs
  4. 52
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EfCoreDatabaseProviderHelper.cs
  5. 6
      framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo.Abp.EntityFrameworkCore.Tests.csproj
  6. 111
      framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/EfCoreDatabaseProviderHelper_Tests.cs

15
docs/en/studio/release-notes.md

@ -9,7 +9,20 @@
This document contains **brief release notes** for each ABP Studio release. Release notes only include **major features** and **visible enhancements**. Therefore, they don't include all the development done in the related version.
## 2.2.6 (2026-04-08) Latest
## 2.2.7 (2026-04-20) Latest
* Improved Blazor WebApp template setup for easier tiered application development
* Added application version tracking in analytics events
* Fixed issues in Basic Theme public website templates
* Improved PostgreSQL vector database support in templates
* Enhanced Blazor CRUD support with built-in Book management example
* Modernized React Native template components
* Updated to ABP 10.3 and Blazorise 2.0.4
* Improved run profile and PowerShell execution reliability
* Added AI Management and Rate Limiting modules to available module options
## 2.2.6 (2026-04-08)
- Disable Scriban 7.0 cumulative output limit for template rendering

1
docs/en/studio/version-mapping.md

@ -11,6 +11,7 @@ This document provides a general overview of the relationship between various ve
| **ABP Studio Version** | **ABP Version of Startup Template** |
|------------------------|---------------------------|
| 2.2.7 | 10.3.0 |
| 2.2.5 - 2.2.6 | 10.2.0 |
| 2.2.2 - 2.2.4 | 10.1.1 |
| 2.2.1 | 10.1.0 |

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

@ -197,29 +197,7 @@ public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext,
protected virtual EfCoreDatabaseProvider? GetDatabaseProviderOrNull(ModelBuilder modelBuilder)
{
switch (Database.ProviderName)
{
case "Microsoft.EntityFrameworkCore.SqlServer":
return EfCoreDatabaseProvider.SqlServer;
case "Npgsql.EntityFrameworkCore.PostgreSQL":
return EfCoreDatabaseProvider.PostgreSql;
case "Pomelo.EntityFrameworkCore.MySql":
case "MySql.Data.MySqlClient":
return EfCoreDatabaseProvider.MySql;
case "Oracle.EntityFrameworkCore":
case "Devart.Data.Oracle.Entity.EFCore":
return EfCoreDatabaseProvider.Oracle;
case "Microsoft.EntityFrameworkCore.Sqlite":
return EfCoreDatabaseProvider.Sqlite;
case "Microsoft.EntityFrameworkCore.InMemory":
return EfCoreDatabaseProvider.InMemory;
case "FirebirdSql.EntityFrameworkCore.Firebird":
return EfCoreDatabaseProvider.Firebird;
case "Microsoft.EntityFrameworkCore.Cosmos":
return EfCoreDatabaseProvider.Cosmos;
default:
return null;
}
return EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(Database.ProviderName);
}
public async override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)

52
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EfCoreDatabaseProviderHelper.cs

@ -0,0 +1,52 @@
using System;
namespace Volo.Abp.EntityFrameworkCore;
public static class EfCoreDatabaseProviderHelper
{
public static EfCoreDatabaseProvider? GetDatabaseProviderOrNull(string? providerName)
{
if (providerName.IsNullOrWhiteSpace())
{
return null;
}
if (providerName.Contains("SqlServer", StringComparison.OrdinalIgnoreCase))
{
return EfCoreDatabaseProvider.SqlServer;
}
if (providerName.Contains("Npgsql", StringComparison.OrdinalIgnoreCase) ||
providerName.Contains("PostgreSQL", StringComparison.OrdinalIgnoreCase))
{
return EfCoreDatabaseProvider.PostgreSql;
}
if (providerName.Contains("MySql", StringComparison.OrdinalIgnoreCase) ||
providerName.Contains("Pomelo", StringComparison.OrdinalIgnoreCase))
{
return EfCoreDatabaseProvider.MySql;
}
if (providerName.Contains("Oracle", StringComparison.OrdinalIgnoreCase) ||
providerName.Contains("Devart", StringComparison.OrdinalIgnoreCase))
{
return EfCoreDatabaseProvider.Oracle;
}
if (providerName.Contains("Sqlite", StringComparison.OrdinalIgnoreCase))
{
return EfCoreDatabaseProvider.Sqlite;
}
if (providerName.Contains("InMemory", StringComparison.OrdinalIgnoreCase))
{
return EfCoreDatabaseProvider.InMemory;
}
if (providerName.Contains("Firebird", StringComparison.OrdinalIgnoreCase))
{
return EfCoreDatabaseProvider.Firebird;
}
if (providerName.Contains("Cosmos", StringComparison.OrdinalIgnoreCase))
{
return EfCoreDatabaseProvider.Cosmos;
}
return null;
}
}

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

@ -17,6 +17,12 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" />
<PackageReference Include="MySql.EntityFrameworkCore" />
<PackageReference Include="Oracle.EntityFrameworkCore" />
</ItemGroup>
</Project>

111
framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/EfCoreDatabaseProviderHelper_Tests.cs

@ -0,0 +1,111 @@
using Microsoft.EntityFrameworkCore;
using Shouldly;
using Xunit;
namespace Volo.Abp.EntityFrameworkCore;
public class EfCoreDatabaseProviderHelper_Tests
{
[Fact]
public void Should_Detect_SqlServer_From_Real_Assembly()
{
var builder = new DbContextOptionsBuilder<EmptyDbContext>();
Microsoft.EntityFrameworkCore.SqlServerDbContextOptionsExtensions.UseSqlServer(builder, "Server=localhost;Database=test");
using var context = new EmptyDbContext(builder.Options);
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(context.Database.ProviderName)
.ShouldBe(EfCoreDatabaseProvider.SqlServer);
}
[Fact]
public void Should_Detect_PostgreSql_From_Real_Assembly()
{
var builder = new DbContextOptionsBuilder<EmptyDbContext>();
Microsoft.EntityFrameworkCore.NpgsqlDbContextOptionsBuilderExtensions.UseNpgsql(builder, "Host=localhost;Database=test");
using var context = new EmptyDbContext(builder.Options);
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(context.Database.ProviderName)
.ShouldBe(EfCoreDatabaseProvider.PostgreSql);
}
[Fact]
public void Should_Detect_MySql_Pomelo_From_Assembly_Name()
{
var providerName = typeof(Microsoft.EntityFrameworkCore.MySqlDbContextOptionsBuilderExtensions).Assembly.GetName().Name;
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(providerName)
.ShouldBe(EfCoreDatabaseProvider.MySql);
}
[Fact]
public void Should_Detect_MySql_Oracle_From_Real_Assembly()
{
var builder = new DbContextOptionsBuilder<EmptyDbContext>();
Microsoft.EntityFrameworkCore.MySQLDbContextOptionsExtensions.UseMySQL(builder, "Server=localhost;Database=test");
using var context = new EmptyDbContext(builder.Options);
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(context.Database.ProviderName)
.ShouldBe(EfCoreDatabaseProvider.MySql);
}
[Fact]
public void Should_Detect_Oracle_From_Real_Assembly()
{
var builder = new DbContextOptionsBuilder<EmptyDbContext>();
Microsoft.EntityFrameworkCore.OracleDbContextOptionsExtensions.UseOracle(builder, "Data Source=localhost/XE");
using var context = new EmptyDbContext(builder.Options);
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(context.Database.ProviderName)
.ShouldBe(EfCoreDatabaseProvider.Oracle);
}
[Fact]
public void Should_Detect_Sqlite_From_Real_Assembly()
{
var builder = new DbContextOptionsBuilder<EmptyDbContext>();
Microsoft.EntityFrameworkCore.SqliteDbContextOptionsBuilderExtensions.UseSqlite(builder, "Data Source=:memory:");
using var context = new EmptyDbContext(builder.Options);
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(context.Database.ProviderName)
.ShouldBe(EfCoreDatabaseProvider.Sqlite);
}
[Fact]
public void Should_Detect_InMemory_From_Real_Assembly()
{
var builder = new DbContextOptionsBuilder<EmptyDbContext>();
Microsoft.EntityFrameworkCore.InMemoryDbContextOptionsExtensions.UseInMemoryDatabase(builder, "test");
using var context = new EmptyDbContext(builder.Options);
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(context.Database.ProviderName)
.ShouldBe(EfCoreDatabaseProvider.InMemory);
}
[Theory]
[InlineData("Devart.Data.Oracle.Entity.EFCore", EfCoreDatabaseProvider.Oracle)]
[InlineData("FirebirdSql.EntityFrameworkCore.Firebird", EfCoreDatabaseProvider.Firebird)]
[InlineData("Microsoft.EntityFrameworkCore.Cosmos", EfCoreDatabaseProvider.Cosmos)]
public void Should_Detect_Providers_Without_Package_Reference(string providerName, EfCoreDatabaseProvider expected)
{
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(providerName).ShouldBe(expected);
}
[Theory]
[InlineData("microsoft.entityframeworkcore.sqlserver", EfCoreDatabaseProvider.SqlServer)]
[InlineData("POMELO.ENTITYFRAMEWORKCORE.MYSQL", EfCoreDatabaseProvider.MySql)]
[InlineData("npgsql.entityframeworkcore.postgresql", EfCoreDatabaseProvider.PostgreSql)]
public void Should_Detect_Providers_Case_Insensitively(string providerName, EfCoreDatabaseProvider expected)
{
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(providerName).ShouldBe(expected);
}
[Theory]
[InlineData(null)]
[InlineData("")]
[InlineData(" ")]
[InlineData("Some.Unknown.Provider")]
public void Should_Return_Null_For_Unknown_Or_Empty(string? providerName)
{
EfCoreDatabaseProviderHelper.GetDatabaseProviderOrNull(providerName).ShouldBeNull();
}
private class EmptyDbContext : DbContext
{
public EmptyDbContext(DbContextOptions<EmptyDbContext> options) : base(options)
{
}
}
}
Loading…
Cancel
Save