Я использую SQLCipher для шифрования БД sqlite в приложении WPF. Согласно знаниям, они рекомендуют использовать шаблон Singleton для моего класса DbContext
, чтобы обеспечить использование одного экземпляра во всем моем приложении для повышения производительности.
Ниже приведена упрощенная версия кода:
public class MyDbContext : DbContext
{
private static MyDbContext _instance;
private MyDbContext() : base("MyConnectionString") { }
public static MyDbContext Instance
{
get
{
if (_instance == null)
{
_instance = new MyDbContext();
}
return _instance;
}
}
}
Для операций удаления, обновления и вставки я начинаю транзакцию и выполняю операции. Однако иногда я выполняю операции сохранения и обновления из отдельного потока. Проблема возникает, когда один поток выполняет операцию обновления, а основной поток одновременно пытается прочитать данные из базы данных. Это вызывает следующее исключение:
Error occurred while reading from the store provider's data reader. See the inner exception for details.
---> System.InvalidOperationException: Connection was closed, statement was terminated
at System.Data.SQLite.SQLiteDataReader.CheckClosed()
at System.Data.SQLite.SQLiteDataReader.PrivateRead(Boolean ignoreSingleRow)
at System.Data.SQLite.SQLiteDataReader.Read()
Мои вопросы:
Любая помощь или руководство будут оценены по достоинству!
Я не думаю, что в большинстве случаев использования шаблона единицы работы вам нужен синглтон. Это означало бы, что в экземпляре вашего приложения одновременно имеется только одна единица работы.
Я бы порекомендовал эту статью: Learn.microsoft.com/en-us/ef/core/dbcontext-configuration.
«Любая помощь или руководство будут оценены!» - Да: ты делаешь это совершенно неправильно. DbContext
должен быть недолговечным объектом единицы работы , который не разделяется между потоками. Одноэлементный DbContext неверен, это просто и ясно. (Кстати, EF6 и EFCore в этом отношении идентичны).
См. Логику устойчивости соединения и повторных попыток.
Согласно знаниям, они рекомендуют использовать шаблон Singleton для моего класса
DbContext
, чтобы обеспечить использование одного экземпляра во всем моем приложении для повышения производительности.
Это знание на 100% неверно и на 100% является причиной всех ваших проблем; где бы вы ни нашли этот совет: возможно, переоцените, насколько вы доверяете оттуда! Они могут ошибаться только в одной теме, или они могут ошибаться во многих темах, или, может быть, это просто пробел в общении, и то, что они пытаются сообщить, не совсем так, как вы это интерпретировали.
Не делай этого.
DbContext
рассчитан на кратковременный срок службы; вы, конечно, не хотите, чтобы со временем накапливались корзины известных сущностейКороче говоря: используйте DbContext
таким образом, чтобы a: ограничивался конкретной операцией (или набором связанных операций), а b: не разрешал одновременный доступ.
«Насколько мне известно, они рекомендуют использовать шаблон Singleton для моего класса DbContext». Не могли бы вы добавить ссылку на эту рекомендацию?