Поиск по кириллице sqlite linq C#

Не получается никак нормально выполнить поиск в базе данных русских слов. Английские ищет без проблем.

var firstData = from p in db.Entries
                    where p.Name.ToLower() == text.ToLower()
                    select p;

Если в p.Name весь string на англ - то находит, если есть хоть 1 буква на русском - не находит.

Как исправить? Как реализовать поиск? Уже все нервы вытрепал) Спасибо!


Ответы (2 шт):

Автор решения: Андрей Шутов

Нашел решение проблемы Устанавливаем пакет System.Data.SQLite;

И в моем случае решение выглядит так:

SQLiteConnection connection =
        new SQLiteConnection("Data Source=helloapp.db;");
    connection.Open();
    SQLiteCommand command = new SQLiteCommand("SELECT * FROM 'Entries';", connection);
    SQLiteDataReader reader = command.ExecuteReader();
    EntryCollection.Clear();
    foreach (DbDataRecord record in reader)
    {
        var value = record["Name"].ToString().ToLower() == text.ToLower();
        if (value)
        {

            EntryCollection.Add(new Entry
            {
                IdFirmware = record["IdFirmware"].ToString().ToLower(),
                ModelEBM = record["ModelEBM"].ToString().ToLower(),
                StockVersion = record["StockVersion"].ToString().ToLower(),
                Engine = record["Engine"].ToString().ToLower(),
                Broadcast = record["Broadcast"].ToString().ToLower(),
                SpeedLimit = record["SpeedLimit"].ToString().ToLower(),
                Stage1 = record["Stage1"].ToString().ToLower(),
                EURO2 = record["EURO2"].ToString().ToLower(),
                Url = record["Url"].ToString().ToLower()
            });
        }
    }
    connection.Close();
→ Ссылка
Автор решения: Alexander Petrov

СУБД sqlite позволяет задавать Custom collation.

Далее нужно как-то использовать этот collation в LINQ-запросе. Чтобы не мудрить, просто переопределим сопоставление BINARY, которое используется по умолчанию.

using (var db = new ApplicationContext())
{
    var connection = (SqliteConnection)db.Database.GetDbConnection();
    connection.CreateCollation("BINARY", (x, y) => string.Compare(x, y, ignoreCase: true));

    var data = from x in db.Entries
               where x.Name == text
               select x;
    // ...
}

Теперь все сравнения строк внутри этого блока using будут без учёта регистра.


Можно указать сопоставление для конкретной колонки при создании модели:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Entry>(e =>
    {
        e.Property(o => o.Name).HasColumnType("TEXT COLLATE NOCASE");
    });
}

Соответственно, в запросе нужно указывать название этого сопоставления:

CreateCollation("NOCASE"

Можно пойти ещё дальше и задать сопоставление в конструкторе контекста:

public ApplicationContext()
{
    var connection = (SqliteConnection)Database.GetDbConnection();
    connection.CreateCollation("NOCASE", (x, y) => string.Compare(x, y, ignoreCase: true));
}

Теперь оно будет применено для всех LINQ-запросов. Это удобно, но может нарушить работу других запросов, где не требуется сравнение строк без учёта регистра. Однако, помним, что по умолчанию используется BINARY.

→ Ссылка