Поиск по кириллице 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();
СУБД 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.