Browse Source

Merge pull request #23392 from abpframework/MySql.EntityFrameworkCore

Support both `MySql.EntityFrameworkCore` & `Pomelo.EntityFrameworkCore.MySql`.
pull/23414/head
Halil İbrahim Kalkan 1 year ago
committed by GitHub
parent
commit
9175128e3e
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 5
      Directory.Packages.props
  2. 12
      docs/en/framework/data/entity-framework-core/mysql.md
  3. 7
      framework/Volo.Abp.sln
  4. 3
      framework/src/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo/FodyWeavers.xml
  5. 30
      framework/src/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo/FodyWeavers.xsd
  6. 0
      framework/src/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo/Microsoft/EntityFrameworkCore/AbpPomeloMySQLModelBuilderExtensions.cs
  7. 27
      framework/src/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo.csproj
  8. 33
      framework/src/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo/Volo/Abp/EntityFrameworkCore/AbpDbContextConfigurationContextMySQLExtensions.cs
  9. 29
      framework/src/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo/Volo/Abp/EntityFrameworkCore/AbpDbContextOptionsMySQLExtensions.cs
  10. 40
      framework/src/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo/Volo/Abp/EntityFrameworkCore/ConnectionStrings/PomeloMySQLConnectionStringChecker.cs
  11. 27
      framework/src/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo/Volo/Abp/EntityFrameworkCore/MySQL/AbpEntityFrameworkCoreMySQLPomeloModule.cs
  12. 12
      framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Microsoft/EntityFrameworkCore/AbpMySQLModelBuilderExtensions.cs
  13. 2
      framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo.Abp.EntityFrameworkCore.MySQL.csproj
  14. 19
      framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo/Abp/EntityFrameworkCore/AbpDbContextConfigurationContextMySQLExtensions.cs
  15. 7
      framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo/Abp/EntityFrameworkCore/AbpDbContextOptionsMySQLExtensions.cs
  16. 4
      framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo/Abp/EntityFrameworkCore/ConnectionStrings/MySQLConnectionStringChecker.cs
  17. 1
      nupkg/common.ps1

5
Directory.Packages.props

@ -136,7 +136,8 @@
<PackageVersion Include="Oracle.EntityFrameworkCore" Version="9.23.80" />
<PackageVersion Include="Polly" Version="8.5.2" />
<PackageVersion Include="Polly.Extensions.Http" Version="3.0.0" />
<PackageVersion Include="Pomelo.EntityFrameworkCore.MySql" Version="9.0.0-preview.3.efcore.9.0.0" />
<PackageVersion Include="Pomelo.EntityFrameworkCore.MySql" Version="9.0.0-rc.1.efcore.9.0.0" />
<PackageVersion Include="MySql.EntityFrameworkCore" Version="9.0.6" />
<PackageVersion Include="Quartz" Version="3.14.0" />
<PackageVersion Include="Quartz.Extensions.DependencyInjection" Version="3.14.0" />
<PackageVersion Include="Quartz.Plugins.TimeZoneConverter" Version="3.14.0" />
@ -185,4 +186,4 @@
<PackageVersion Include="ConfigureAwait.Fody" Version="3.3.2" />
<PackageVersion Include="Fody" Version="6.9.2" />
</ItemGroup>
</Project>
</Project>

12
docs/en/framework/data/entity-framework-core/mysql.md

@ -17,10 +17,20 @@ Find ***YourProjectName*EntityFrameworkCoreModule** class inside the `.EntityFra
Find `UseSqlServer()` calls in your solution. Check the following files:
* *YourProjectName*EntityFrameworkCoreModule.cs inside the `.EntityFrameworkCore` project. Replace `UseSqlServer()` with `UseMySQL()`.
* *YourProjectName*DbContextFactory.cs inside the `.EntityFrameworkCore` project. Replace `UseSqlServer()` with `UseMySql()`. Then add a new parameter (`ServerVersion`) to `UseMySql()` method. Example: `.UseMySql(configuration.GetConnectionString("Default"), ServerVersion.Parse("8.0.21-mysql"))`. See [this issue](https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/pull/1233) for more information about `ServerVersion`)
* *YourProjectName*DbContextFactory.cs inside the `.EntityFrameworkCore` project. Replace `UseSqlServer()` with `UseMySQL()`.
> Depending on your solution structure, you may find more code files need to be changed.
## Use Pomelo Provider
Alternatively, you can use the [Pomelo.EntityFrameworkCore.MySql](https://www.nuget.org/packages/Pomelo.EntityFrameworkCore.MySql) provider. Replace the [Volo.Abp.EntityFrameworkCore.MySQL](https://www.nuget.org/packages/Volo.Abp.EntityFrameworkCore.MySQL) package with the [Volo.Abp.EntityFrameworkCore.MySQL.Pomelo](https://www.nuget.org/packages/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo) package in your `.EntityFrameworkCore` project.
Find ***YourProjectName*EntityFrameworkCoreModule** class inside the `.EntityFrameworkCore` project, replace `typeof(AbpEntityFrameworkCoreMySQLModule)` with `typeof(AbpEntityFrameworkCoreMySQLPomeloModule)` in the `DependsOn` attribute.
> Depending on your solution structure, you may find more code files need to be changed.
The `UseMySQL()` method calls remain the same, no changes needed.
## Change the Connection Strings
MySQL connection strings are different than SQL Server connection strings. So, check all `appsettings.json` files in your solution and replace the connection strings inside them. See the [connectionstrings.com](https://www.connectionstrings.com/mysql) for details of MySQL connection string options.

7
framework/Volo.Abp.sln

@ -491,6 +491,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.BlobStoring.Bunny.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Timing.Tests", "test\Volo.Abp.Timing.Tests\Volo.Abp.Timing.Tests.csproj", "{58FCF22D-E8DB-4EB8-B586-9BB6E9899D64}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.EntityFrameworkCore.MySQL.Pomelo", "src\Volo.Abp.EntityFrameworkCore.MySQL.Pomelo\Volo.Abp.EntityFrameworkCore.MySQL.Pomelo.csproj", "{5B49FE47-A4C5-45BE-A903-8215CF5E2FAF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -1465,6 +1467,10 @@ Global
{58FCF22D-E8DB-4EB8-B586-9BB6E9899D64}.Debug|Any CPU.Build.0 = Debug|Any CPU
{58FCF22D-E8DB-4EB8-B586-9BB6E9899D64}.Release|Any CPU.ActiveCfg = Release|Any CPU
{58FCF22D-E8DB-4EB8-B586-9BB6E9899D64}.Release|Any CPU.Build.0 = Release|Any CPU
{5B49FE47-A4C5-45BE-A903-8215CF5E2FAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5B49FE47-A4C5-45BE-A903-8215CF5E2FAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5B49FE47-A4C5-45BE-A903-8215CF5E2FAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5B49FE47-A4C5-45BE-A903-8215CF5E2FAF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -1712,6 +1718,7 @@ Global
{1BBCBA72-CDB6-4882-96EE-D4CD149433A2} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{BC4BB2D6-DFD8-4190-AAC3-32C0A7A8E915} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{58FCF22D-E8DB-4EB8-B586-9BB6E9899D64} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{5B49FE47-A4C5-45BE-A903-8215CF5E2FAF} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}

3
framework/src/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
framework/src/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

0
framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Microsoft/EntityFrameworkCore/AbpMySqlModelBuilderExtensions.cs → framework/src/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo/Microsoft/EntityFrameworkCore/AbpPomeloMySQLModelBuilderExtensions.cs

27
framework/src/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo.csproj

@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<AssemblyName>Volo.Abp.EntityFrameworkCore.MySQL.Pomelo</AssemblyName>
<PackageId>Volo.Abp.EntityFrameworkCore.MySQL.Pomelo</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.EntityFrameworkCore\Volo.Abp.EntityFrameworkCore.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" />
</ItemGroup>
</Project>

33
framework/src/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo/Volo/Abp/EntityFrameworkCore/AbpDbContextConfigurationContextMySQLExtensions.cs

@ -0,0 +1,33 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using System;
using Volo.Abp.EntityFrameworkCore.DependencyInjection;
namespace Volo.Abp.EntityFrameworkCore;
public static class AbpDbContextConfigurationContextMySQLExtensions
{
public static DbContextOptionsBuilder UseMySQL(
[NotNull] this AbpDbContextConfigurationContext context,
Action<Microsoft.EntityFrameworkCore.Infrastructure.MySqlDbContextOptionsBuilder>? mySQLOptionsAction = null)
{
if (context.ExistingConnection != null)
{
return context.DbContextOptions.UseMySql(context.ExistingConnection,
ServerVersion.AutoDetect(context.ConnectionString), optionsBuilder =>
{
optionsBuilder.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
mySQLOptionsAction?.Invoke(optionsBuilder);
});
}
else
{
return context.DbContextOptions.UseMySql(context.ConnectionString,
ServerVersion.AutoDetect(context.ConnectionString), optionsBuilder =>
{
optionsBuilder.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
mySQLOptionsAction?.Invoke(optionsBuilder);
});
}
}
}

29
framework/src/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo/Volo/Abp/EntityFrameworkCore/AbpDbContextOptionsMySQLExtensions.cs

@ -0,0 +1,29 @@
using JetBrains.Annotations;
using System;
using Microsoft.EntityFrameworkCore.Infrastructure;
namespace Volo.Abp.EntityFrameworkCore;
public static class AbpDbContextOptionsMySQLExtensions
{
public static void UseMySQL(
[NotNull] this AbpDbContextOptions options,
Action<MySqlDbContextOptionsBuilder>? mySQLOptionsAction = null)
{
options.Configure(context =>
{
context.UseMySQL(mySQLOptionsAction);
});
}
public static void UseMySQL<TDbContext>(
[NotNull] this AbpDbContextOptions options,
Action<MySqlDbContextOptionsBuilder>? mySQLOptionsAction = null)
where TDbContext : AbpDbContext<TDbContext>
{
options.Configure<TDbContext>(context =>
{
context.UseMySQL(mySQLOptionsAction);
});
}
}

40
framework/src/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo/Volo/Abp/EntityFrameworkCore/ConnectionStrings/PomeloMySQLConnectionStringChecker.cs

@ -0,0 +1,40 @@
using System;
using System.Threading.Tasks;
using MySqlConnector;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.EntityFrameworkCore.ConnectionStrings;
[Dependency(ReplaceServices = true)]
public class PomeloMySQLConnectionStringChecker : IConnectionStringChecker, ITransientDependency
{
public virtual async Task<AbpConnectionStringCheckResult> CheckAsync(string connectionString)
{
var result = new AbpConnectionStringCheckResult();
try
{
var connString = new MySqlConnectionStringBuilder(connectionString)
{
ConnectionLifeTime = 1
};
var oldDatabaseName = connString.Database;
connString.Database = "mysql";
await using var conn = new MySqlConnection(connString.ConnectionString);
await conn.OpenAsync();
result.Connected = true;
await conn.ChangeDatabaseAsync(oldDatabaseName);
result.DatabaseExists = true;
await conn.CloseAsync();
return result;
}
catch (Exception)
{
return result;
}
}
}

27
framework/src/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo/Volo/Abp/EntityFrameworkCore/MySQL/AbpEntityFrameworkCoreMySQLPomeloModule.cs

@ -0,0 +1,27 @@
using Volo.Abp.EntityFrameworkCore.GlobalFilters;
using Volo.Abp.Guids;
using Volo.Abp.Modularity;
namespace Volo.Abp.EntityFrameworkCore.MySQL;
[DependsOn(
typeof(AbpEntityFrameworkCoreModule)
)]
public class AbpEntityFrameworkCoreMySQLPomeloModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpSequentialGuidGeneratorOptions>(options =>
{
if (options.DefaultSequentialGuidType == null)
{
options.DefaultSequentialGuidType = SequentialGuidType.SequentialAsString;
}
});
Configure<AbpEfCoreGlobalFilterOptions>(options =>
{
options.UseDbFunction = true;
});
}
}

12
framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Microsoft/EntityFrameworkCore/AbpMySQLModelBuilderExtensions.cs

@ -0,0 +1,12 @@
using Volo.Abp.EntityFrameworkCore;
namespace Microsoft.EntityFrameworkCore;
public static class AbpMySQLModelBuilderExtensions
{
public static void UseMySQL(
this ModelBuilder modelBuilder)
{
modelBuilder.SetDatabaseProvider(EfCoreDatabaseProvider.MySql);
}
}

2
framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo.Abp.EntityFrameworkCore.MySQL.csproj

@ -21,7 +21,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" />
<PackageReference Include="MySql.EntityFrameworkCore" />
</ItemGroup>
</Project>

19
framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo/Abp/EntityFrameworkCore/AbpDbContextConfigurationContextMySQLExtensions.cs

@ -1,7 +1,6 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using System;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Volo.Abp.EntityFrameworkCore.DependencyInjection;
namespace Volo.Abp.EntityFrameworkCore;
@ -9,26 +8,16 @@ namespace Volo.Abp.EntityFrameworkCore;
public static class AbpDbContextConfigurationContextMySQLExtensions
{
public static DbContextOptionsBuilder UseMySQL(
[NotNull] this AbpDbContextConfigurationContext context,
Action<MySqlDbContextOptionsBuilder>? mySQLOptionsAction = null)
[NotNull] this AbpDbContextConfigurationContext context,
Action<MySql.EntityFrameworkCore.Infrastructure.MySQLDbContextOptionsBuilder>? mySQLOptionsAction = null)
{
if (context.ExistingConnection != null)
{
return context.DbContextOptions.UseMySql(context.ExistingConnection,
ServerVersion.AutoDetect(context.ConnectionString), optionsBuilder =>
{
optionsBuilder.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
mySQLOptionsAction?.Invoke(optionsBuilder);
});
return context.DbContextOptions.UseMySQL(context.ExistingConnection, mySQLOptionsAction);
}
else
{
return context.DbContextOptions.UseMySql(context.ConnectionString,
ServerVersion.AutoDetect(context.ConnectionString), optionsBuilder =>
{
optionsBuilder.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
mySQLOptionsAction?.Invoke(optionsBuilder);
});
return context.DbContextOptions.UseMySQL(context.ConnectionString, mySQLOptionsAction);
}
}
}

7
framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo/Abp/EntityFrameworkCore/AbpDbContextOptionsMySQLExtensions.cs

@ -1,14 +1,13 @@
using JetBrains.Annotations;
using System;
using Microsoft.EntityFrameworkCore.Infrastructure;
namespace Volo.Abp.EntityFrameworkCore;
public static class AbpDbContextOptionsMySQLExtensions
{
public static void UseMySQL(
[NotNull] this AbpDbContextOptions options,
Action<MySqlDbContextOptionsBuilder>? mySQLOptionsAction = null)
[NotNull] this AbpDbContextOptions options,
Action<MySql.EntityFrameworkCore.Infrastructure.MySQLDbContextOptionsBuilder>? mySQLOptionsAction = null)
{
options.Configure(context =>
{
@ -18,7 +17,7 @@ public static class AbpDbContextOptionsMySQLExtensions
public static void UseMySQL<TDbContext>(
[NotNull] this AbpDbContextOptions options,
Action<MySqlDbContextOptionsBuilder>? mySQLOptionsAction = null)
Action<MySql.EntityFrameworkCore.Infrastructure.MySQLDbContextOptionsBuilder>? mySQLOptionsAction = null)
where TDbContext : AbpDbContext<TDbContext>
{
options.Configure<TDbContext>(context =>

4
framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo/Abp/EntityFrameworkCore/ConnectionStrings/MySqlConnectionStringChecker.cs → framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo/Abp/EntityFrameworkCore/ConnectionStrings/MySQLConnectionStringChecker.cs

@ -1,13 +1,13 @@
using System;
using System.Threading.Tasks;
using MySqlConnector;
using MySql.Data.MySqlClient;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.EntityFrameworkCore.ConnectionStrings;
[Dependency(ReplaceServices = true)]
public class MySqlConnectionStringChecker : IConnectionStringChecker, ITransientDependency
public class MySQLConnectionStringChecker : IConnectionStringChecker, ITransientDependency
{
public virtual async Task<AbpConnectionStringCheckResult> CheckAsync(string connectionString)
{

1
nupkg/common.ps1

@ -178,6 +178,7 @@ $projects = (
"framework/src/Volo.Abp.Emailing",
"framework/src/Volo.Abp.EntityFrameworkCore",
"framework/src/Volo.Abp.EntityFrameworkCore.MySQL",
"framework/src/Volo.Abp.EntityFrameworkCore.MySQL.Pomelo",
"framework/src/Volo.Abp.EntityFrameworkCore.Oracle",
"framework/src/Volo.Abp.EntityFrameworkCore.Oracle.Devart",
"framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql",

Loading…
Cancel
Save