ASP.NET Core framework ve verzi 2 obsahuje standardně podporu Microsoft SQL Serveru a SQL Lite. Pokud však z jakýchkoliv důvodů chcete pro data použít databázi MySQL/MariaDB pak je zatím stále potřeba podporu nainstalovat. Podíváme se jak na to.
Přehled komponent
V době psaní toho článku jsou k dispozici v podstatě dvě komponenty
NuGet Package | Autor |
Pomelo.EntityFrameworkCore.MySql | Pomelo Foundation Project |
MySql.Data.EntityFrameworkCore | MySQL project (Oracle) |
Já jsem se po přečtení pár článků rozhodl pro komponentu Pomela, jelikož Oracle ve své komponentě neřeší vše podle standardů Microsoftu pro ostatní databáze.
Instalace komponenty
Pokud používáme Microsoft Visual Studio Code pak stačí přidat jeden řádek mezi reference .csproj:
<Project Sdk="Microsoft.NET.Sdk.Web">
...
<ItemGroup>
...
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.1.1" />
</ItemGroup>
</Project>
Pokud používáme Microsoft Visual Studio pak můžeme použít NuGet explorer:
Konfigurace
Prvním krokem je úprava Startup.cs, konkrétně části ConfigureServices:
...
using Pomelo.EntityFrameworkCore.MySql;
...
public void ConfigureServices(IServiceCollection services)
{
...
services.AddDbContext<YourDbContext>(options =>
options
.useMySql(
Configuration.GetConnectionString("MySQL")));
...
Další krok už je potřeba jen pokud jste využili Identity frameworku. Ten má v základu nadefinované určité primární a unikátní klíče tak, že s tím má MySQL v kombinaci s UTF8 problém.
Doporučované kódování databáze je utf8mb4
, přičemž pokud si nejste jistí co máte nastaveno, pak můžete použít tento příkaz:
show variables like 'character_set_database';
Využijeme tedy vlastnosti DBContext třídy, kde máme ještě možnost „ladit“ vlastnosti jednotlivých modelů a my si tak změníme vlastnosti Identity modelů, které už nám Microsoft předdefinoval.
Konkrétně využijeme metody OnModelCreating, která po úpravě může vypadat nějak takto:
base.OnModelCreating(builder);
// Shorten key length for Identity
builder.Entity<IdentityUser>(entity => {
entity.Property(m => m.Id).HasMaxLength(127);
entity.Property(m => m.NormalizedUserName).HasMaxLength(127);
});
builder.Entity<IdentityRole>(entity => {
entity.Property(m => m.Id).HasMaxLength(127);
entity.Property(m => m.NormalizedName).HasMaxLength(127);
});
builder.Entity<IdentityUserLogin<string>>(entity => {
entity.Property(m => m.LoginProvider).HasMaxLength(127);
entity.Property(m => m.ProviderKey).HasMaxLength(127);
});
builder.Entity<IdentityUserRole<string>>(entity => {
entity.Property(m => m.UserId).HasMaxLength(127);
entity.Property(m => m.RoleId).HasMaxLength(127);
});
builder.Entity<IdentityUserToken<string>>(entity => {
entity.Property(m => m.UserId).HasMaxLength(127);
entity.Property(m => m.LoginProvider).HasMaxLength(127);
entity.Property(m => m.Name).HasMaxLength(127);
});
Aplikace změn modelů
Pokud jsme už vytvořili inicializační migrační model včetně identity frameworku, pak jsme se zřejmě setkali s touhle chybou:
CREATE UNIQUE INDEX `RoleNameIndex` ON `AspNetRoles` (`NormalizedName`);
...
Specified key was too long; max key length is 767 bytes ---> MySql.Data.MySqlClient.MySqlException
Musíme tedy předchozí migraci smazat a vytvořit novou verzi a aplikovat na DB. Dost možná se pak setkáte i s hláškou:
Table 'AspNetRoles' already exists
Bude tedy potřeba promazat i příslušnou tabulku ručně z DB.
Sekvence příkazů pro vytvoření migrace a aplikaci na DB je:
dotnet ef migrations add <nameOfStep>
dotnet ef database update
Vše ostatní zatím vypadá, že funguje stejně jako v případě použití MSQL nebo SQL Lite.
Famózní článek, díky za něj!
Dovolím si doplnit dvě věci (.NET Core 3.1):
1) pokud začínáte s mysql od začátku (nemigrujete na mysql z mssql), vyplatí se odstranit všechny migrace (remove-migration) a pak začít úplně odznova.
2) connection string bude „server=localhost;database=library;user=user;password=password“