ОБНОВЛЕНИЕ 4:
Ого, очевидно, это не проблема EF или конфигурации.
Каким-то образом назначение переменной страницы .razor портит данные.
Не знаю, как теперь поступить с вопросом, но я по крайней мере отредактировал заголовок, чтобы отразитьтекущая проблема, которая является: страница Razor испортила кодировку при назначении специального символа на строку.
Проблема:
Независимо от того, что я делаю символы, я вставляю в MySQL 5.7.17 база данных всегда отображается как �:
Поиск в базе данных
Хотя есть похожие посты, ни одно из решений не сработало для меня, и я исчерпал своивозможности исследования.
Что я пробовал:
Код:
Строка подключения:
"MySQL": "server=localhost;user=root;database=sgn;charset=utf8mb4;"
UserModel.cs
namespace source.Data.Models
{
[MySqlCharset("utf8mb4")]
[MySqlCollation("utf8mb4_unicode_ci")]
public class UserModel
{
public UserModel() { }
[Key]
public long Id { get; set; }
[MySqlCharset("utf8mb4")]
[MySqlCollation("utf8mb4_unicode_ci")]
public string Username { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Language { get; set; }
public string StartPage { get; set; }
}
}
DatabaseContext.cs
namespace source.Data.Database
{
public class DatabaseContext : DbContext
{
private IConfiguration Configuration;
public DbSet<UserModel> Users { get; set; }
public DatabaseContext(DbContextOptions<DatabaseContext> options, IConfiguration configuration)
: base(options)
{
Configuration = configuration;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseMySQL(Configuration.GetSection("AppSettings").GetSection("Database").GetSection("ConnectionString")["MySQL"]);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UserModel>().Property(p => p.Username).IsUnicode(true);
base.OnModelCreating(modelBuilder);
}
}
}
DesignTimeDatabaseContextFactory.cs
namespace source.Data.Database
{
public class DesignTimeDatabaseContextFactory : IDesignTimeDbContextFactory<DatabaseContext>
{
private IConfiguration Configuration;
private AppSettingsService AppSettings;
public DesignTimeDatabaseContextFactory()
{
}
public DesignTimeDatabaseContextFactory(IConfiguration configuration, AppSettingsService appSettings)
{
Configuration = configuration;
AppSettings = appSettings;
}
public DatabaseContext CreateDbContext(string[] args)
{
var builder = new DbContextOptionsBuilder<DatabaseContext>();
builder.UseMySQL(AppSettings.ConnectionString);
return new DatabaseContext(builder.Options, Configuration);
}
}
}
Create.razor - здесь я добавляю пользователя вбаза данных.Обратите внимание, что в этом проекте используется Blazor, поэтому не смущайтесь тегом "@functions".Ни одна из функций не добавляет данные должным образом, и прокомментировал подготовленный оператор, который я пробовал.
<div class="login_form">
<h3>Create Account</h3>
<button @onclick="@(e => AddEntry())">Add DB User!</button><br />
<button @onclick="@(e => AddEntry2())">Add TEST!</button><br />
</div>
@functions {
void AddEntry2()
{
UserModel test = new UserModel();
test.Username = "Test çã";
test.FirstName = "Michel";
test.LastName = "Arendt";
test.Email = "mail@gmail.com";
test.Password = "123";
test.Language = "pt-BR";
test.StartPage = "/Home/";
db.Database.ExecuteSqlCommand("SET NAMES utf8mb4");
db.Database.ExecuteSqlCommand("SET character_set_connection = utf8mb4");
db.Database.ExecuteSqlCommand("INSERT INTO Users (Username) VALUES (N'" + test.Username + "')");
db.SaveChanges();
//using (SqlConnection connection = new SqlConnection(AppSettings.DatabaseConnectionString()))
//{
// connection.Open();
// SqlCommand command = new SqlCommand(null, connection);
// // Create and prepare an SQL statement.
// command.CommandText =
// "INSERT INTO Users (Username) " +
// "VALUES (@username)";
// SqlParameter username = new SqlParameter("@username", SqlDbType.NVarChar, 100);
// username.Value = "Garçon";
// command.Parameters.Add(username);
// // Call Prepare after setting the Commandtext and Parameters.
// command.Prepare();
// command.ExecuteNonQuery();
//}
}
void AddEntry()
{
UserModel waitress = new UserModel();
waitress.Username = "Garçon";
waitress.FirstName = "Test";
waitress.LastName = "Test";
waitress.Email = "mail@gmail.com";
waitress.Password = "123";
waitress.Language = "pt-BR";
waitress.StartPage = "/Home/";
db.Users.Add(waitress);
db.SaveChanges();
}
}
source.csproj (Справочник зависимостей)
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<LangVersion>7.3</LangVersion>
<RestorePackages>false</RestorePackages>
<Version>0.10.0</Version>
<Authors>Michel Arendt</Authors>
<Product>SGN</Product>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Content Remove="compilerconfig.json" />
</ItemGroup>
<ItemGroup>
<None Include="compilerconfig.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="ElectronNET.API" Version="5.22.13" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.2.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.0.0-preview6.19304.6" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" />
<PackageReference Include="MySql.Data.EntityFrameworkCore" Version="8.0.16" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.5.0" />
</ItemGroup>
<ItemGroup>
<Content Update="electron.manifest.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
Конфигурация базы данных
Параметры сортировки и набора символов по умолчанию для базы данных и столбцов: utf8mb4_unicode_ci и utf8mb4 соответственно:
Набор символов и параметры сортировки по умолчанию
Набор символов и сопоставление столбцов
Любые идеи о том, что еще я мог бы попробовать, чтобы исправить эту проблему или какую ошибку я совершаю?
Заранее спасибо!
ОБНОВЛЕНИЕ:
Я переключился на Pomelo.EntityFrameworkCore.MySql , как предложил Брэдли Грейнджер (в комментариях), но это не помогло решить проблему.Мои измененные файлы теперь:
Изменена сборка с Startup.cs и DesignTimeDatabaseContextFactory.cs для использования:
builder
.UseMySql(AppSettings.ConnectionString,
mysqlOptions =>
{
mysqlOptions
.CharSetBehavior(CharSetBehavior.AppendToAllColumns)
.AnsiCharSet(CharSet.Utf8mb4)
.UnicodeCharSet(CharSet.Utf8mb4);
});
Create.razor
void AddEntry2()
{
UserModel test = new UserModel();
test.Username = "Test çã";
test.FirstName = "Michel";
test.LastName = "Arendt";
test.Email = "mail@gmail.com";
test.Password = "123";
test.Language = "pt-BR";
test.StartPage = "/Home/";
using (MySqlConnection connection = new MySqlConnection(AppSettings.ConnectionString))
{
connection.Open();
MySqlCommand command = new MySqlCommand(null, connection);
// Create and prepare an SQL statement.
command.CommandText =
"INSERT INTO Users (Username) " +
"VALUES (@username)";
MySqlParameter username = new MySqlParameter("@username", MySqlDbType.LongText, 100);
username.Value = "Garçon";
command.Parameters.Add(username);
// Call Prepare after setting the Commandtext and Parameters.
command.Prepare();
command.ExecuteNonQuery();
}
}
Я подумал, что это поможет, поэтому я также настроил инициализацию MySQL (my.ini) на локальном сервере:
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
Однаконичего не получалось.Любые другие идеи?
ОБНОВЛЕНИЕ 2:
Чтобы разобраться, если это проблема с базой данных или EF Core, я установил простой PHP-скрипт для вставки той же записи вбаза данных.
На этом изображении записи 1 и 2 вставлены из EF Core, а запись 3 были вставлены из PHP
Как видно из изображения, на которое похоже база данныхвсе будет в порядке, так как вставка из PHP работала нормально.
Как убедиться, что EF Core использует кодировку "utf8mb4" при добавлении записи?