#c# #delphi #.net-core #entity-framework-core #firebird
#c# #delphi #.net-ядро #entity-framework-core #firebird
Вопрос:
Я переношу устаревшую систему, созданную на Delphi FireDAC, на C # EF. Поскольку это устаревшая система, уже существует база данных со многими записями (многие записи без информации о кодировании).
Когда я получаю записи, содержащие специальные символы, используя C # EF, символы отображаются некорректно.
Как я могу решить эту проблему?
C#
Delphi
MainWindow.xaml.cs — Кнопка Click
private void Button_Click(object sender, RoutedEventArgs e)
{
string appPath = AppContext.BaseDirectory;
string connectionString = $"database=localhost/3050:{appPath}\database\test.fdb;user=sysdba;password=masterkey";
using (AppDbContext con = new AppDbContext(connectionString))
{
Product p = con.Products.First();
lblText.Text = p.Name;
}
}
AppDbContext.cs
public class AppDbContext : DbContext
{
private readonly string _connectionString;
public DbSet<Product> Products { get; set; }
public AppDbContext(string connectionString)
{
_connectionString = connectionString;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.UseFirebird(_connectionString);
}
}
Product.cs
[Table("PRODUCTS")]
public class Product
{
[Column("ID")]
public int Id { get; set; }
[Column("NAME")]
public string Name { get; set; }
}
Ответ №1:
В firebird в большинстве случаев проблемы со специальными символами могут быть решены с использованием кодировки UTF-8. Внутри connectionString
может потребоваться включить charset=utf8
.
Добавлено обновление:
Спасибо @Felipe Godinho за отзыв, похоже, charset=win1252
было обнаружено, что это еще один ценный вариант кодировки, который стоит попробовать при работе с устаревшей системой баз данных, работающей на Firebird.
Комментарии:
1. Я уже пытался передать charset = utf8, и все же проблема продолжалась. Я попробовал с charset = win1252 и проблема решена. Большое вам спасибо.
2. @FelipeGodinho В Delphi до 2009 года (не в Юникоде) использовались кодовые страницы ANSI-xxxx Windows (MBCS, каждая буква обычно равна одному байту или более) строк.
int GetACP(void)
Функция Win32 API. Delphi с 2009 года использует строки UTF-16 внутри, точно так же, как Java и C #. Поскольку вы цитируете FireDAC, а не AnyDAC, вы используете какую-либо версию Delphi 2015 года или более позднюю. Даже тогда, даже если сама база данных не имеет кодировки — тогда кодировка может быть в самих определениях столбцов. И, кроме того, соединение может иметь это. Лично я бы использовал что-то вроде fbprofiler.sf.net и проверьте последовательность подключения из приложения Delphi к FB srv3.
charset=utf8 and yet the problem continued. I tried with charset=win1252
этот OTOH действительно выглядит так, как будто текстовые поля были сохранены в виде необработанного двоичного файла. Но тогда вы абсолютно уверены, что ваша Windows имеет 1252 в качестве кодовой страницы ANSI по умолчанию, а не 1250 или какую-либо другую? Это можно проверить в реестре, возможно, на какой-нибудь панели управления (не уверен) или из Delphi (для нового графического приложения VCL вам нужно только создатьOnShow
обработчик событий основной формы и поместить тудаShowMessage('Code Page is ' IntToStr(GetACP()));
команду).4. В любом случае, оно останется очень хрупким. Правильным способом было бы выгрузить все
schema
(метаданные, часть объявления) базы данных в SQL-скрипт, затем изменить сценарий, чтобы явно объявить кодировку (UTF8 или Win1252 или что-нибудь еще) и параметры сортировки, затем создать новую базу данных и «перекачать» данные (десятилетия назад был инструмент IBDataPump, сегодня есть и другие, вероятно, похожие инструменты, или вы можете сделать это самостоятельно, если отсортировать все таблицы по зависимостям) со старого на новый. Это неявное требование «мы имеем в виду текст cp1251 в наших необработанных двоичных полях» остается скрытой миной, ожидающей взрыва.5. однажды кто-нибудь скажет вам: «мы дали вам деньги на написание нового, не устаревшего приложения, и теперь вы должны поддерживать все неевропейские буквы тоже за одну ночь», и вам все равно придется конвертировать DB в явный UTF8 🙂 Кроме того, возможно, преобразование базы данных и исправление свойства кодировки Delphi FireDAC также сделало бы приложение несколько менее устаревшим 😀