Кодирование ядра EF с Firebird 2.5

#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; }
}
  

Завершите код проекта C #

Ответ №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 srv

3. 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 также сделало бы приложение несколько менее устаревшим 😀