Проблемы с использованием Entity Framework 6 и SQLite
Я пытаюсь использовать Entity Framework с SQLite. У меня возникли проблемы с интеграцией его в основное приложение, поэтому я начал немного проверять с нуля, точно следуя указаниям http://brice-lambson.blogspot.com/2012/10/entity-framework-on-sqlite.html
После того как все сказано и сделано, я получаю следующую ошибку при запуске проекта:
Нет провайдера инфраструктуры Entity Framework для поставщика ADO.NET с инвариантное имя "System.Data.SQLite". Убедитесь, что поставщик зарегистрированный в разделе "entityFramework" в конфигурации приложения файл. Подробнее см. http://go.microsoft.com/fwlink/?LinkId=260882. информация.
Мой app.config выглядит следующим образом:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
</configSections>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<add name="SQLite Data Provider"
invariant="System.Data.SQLite"
description="Data Provider for SQLite"
type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
</DbProviderFactories>
</system.data>
<connectionStrings>
<add name="ChinookContext"
connectionString=
"Data Source=|DataDirectory|Chinook_Sqlite_AutoIncrementPKs.sqlite"
providerName="System.Data.SQLite" />
</connectionStrings>
</configuration>
Затем я увидел его сообщение о Entity Framework 6. Хотя это была не точная ошибка, которую я получал, я попытался установить его обновленного поставщика через NuGet. Ошибка исчезла, но заменилась на следующую:
Не удалось загрузить файл или сборку 'System.Data.SQLite.Linq, Версия = 2.0.88.0, Культура = нейтральная, PublicKeyToken = db937bc2d44ff139 'или одной из его зависимостей. Установленное определение манифеста сборки не соответствует ссылке на сборку. (Исключение из HRESULT: 0x80131040)
Кроме того, мой app.config изменился (слегка) на это:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
</configSections>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="System.Data.SQLite" type="System.Data.SQLite.SQLiteProviderServices, System.Data.SQLite.Linq, Version=2.0.88.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<add name="SQLite Data Provider" invariant="System.Data.SQLite" description="Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
<remove invariant="System.Data.SQLite" />
</DbProviderFactories>
</system.data>
<connectionStrings>
<add name="ChinookContext" connectionString="Data Source=|DataDirectory|Chinook_Sqlite_AutoIncrementPKs.sqlite" providerName="System.Data.SQLite" />
</connectionStrings>
</configuration>
Я пробовал все, что мог придумать для устранения этих ошибок, ничего не сработало. Я пробовал использовать другие двоичные файлы SQLite; Я попытался вручную отредактировать проект SQLite для использования EF версии 6; Я изменил архитектуры, я добавил и удалил пакеты nuget снова и снова и т.д.
Я не знаю, куда идти отсюда.
Ответы
Ответ 1
Основываясь на комментарии magicandre1981, я стал более внимательно смотреть на синтаксис провайдера node. Я обнаружил, что моя сборка была другой версией, чем то, что было указано в атрибуте type, хотя я не вставил или не коснулся этой конкретной строки. Удалив сильное имя, я получил .Net, чтобы загрузить библиотеку. Для справки, здесь новая строка:
<provider invariantName="System.Data.SQLite" type="System.Data.SQLite.SQLiteProviderServices, System.Data.SQLite.Linq" />
Это вернуло меня на правильный путь, и я смог сопоставить результаты с теми, что были в блоге.
Однако я вынужден отметить, что я решил, что SQLite не подходит для Entity Framework, так как слишком много критических функций отсутствует. Я переключился на SQL Server Compact Edition, который я установил через NuGet. Простая настройка для моей строки подключения и я работали с полной мощью Entity Framework. Это заняло меньше минуты, по сравнению с многочасовым опросом, который был SQLite. Я бы рекомендовал переключать базы данных, если это возможно, System.Data.SQLite просто не готов для платформы Entity Framework.
Ответ 2
Просто подумал, что я поделюсь другим способом настройки EF6 с помощью SQLite без использования app.config
/web.config
. EF6 теперь поддерживает конфигурации на основе кода, как описано здесь в msdn. Я использовал следующий код (обновленный, чтобы удалить отражение благодаря Sly):
public class SQLiteConfiguration : DbConfiguration
{
public SQLiteConfiguration()
{
SetProviderFactory("System.Data.SQLite", SQLiteFactory.Instance);
SetProviderFactory("System.Data.SQLite.EF6", SQLiteProviderFactory.Instance);
SetProviderServices("System.Data.SQLite", (DbProviderServices)SQLiteProviderFactory.Instance.GetService(typeof(DbProviderServices)));
}
}
Я использую это, поэтому я могу вставлять правильный DbContext
и, следовательно, DbProvider
во время выполнения и не нуждаюсь во всех настройках в основной сборке.
Edit:
Как Рейн сказал, вам также нужно добавить IDbConnectionFactory
для SQLite, если вы хотите, чтобы ваша строка подключения в вашем файле web.config
/app.config
, Другой подход заключается в вызове другого базового конструктора из вашего DbContext
, который передается в новом SQLiteConnection
, а не в строке подключения, как показано в этом ответе.
Ответ 3
Я знаю, что это старый вопрос, но никто, кажется, не дал ответа, который фактически использует файл .config. Вот раздел system.data и entityframework моего web.config, который позволяет подключаться к базам данных SQLServer и Sqlite:
<system.data>
<DbProviderFactories>
<remove invariant="System.Data.SQLite.EF6" />
<add name="SQLite Data Provider (Entity Framework 6)"
invariant="System.Data.SQLite.EF6"
description=".NET Framework Data Provider for SQLite (Entity Framework 6)"
type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
<remove invariant="System.Data.SQLite" />
<add name="SQLite Data Provider" invariant="System.Data.SQLite"
description=".Net Framework Data Provider for SQLite"
type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
</DbProviderFactories>
</system.data>
<entityFramework>
<providers>
<provider invariantName="System.Data.SQLite.EF6"
type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
<provider invariantName="System.Data.SqlClient"
type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="System.Data.SQLite"
type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
</providers>
</entityFramework>
Ответ 4
Для всех, кто использует настройку на основе кода и все еще получает одно и то же исключение: мне нужно было дополнительно установить соединение factory в ответе kjbartel.
public class SQLiteConnectionFactory : IDbConnectionFactory
{
public DbConnection CreateConnection(string nameOrConnectionString)
{
return new SQLiteConnection(nameOrConnectionString);
}
}
Затем установите соединение по умолчанию factory в SQLiteConfiguration
public class SQLiteConfiguration : DbConfiguration
{
public SQLiteConfiguration()
{
SetDefaultConnectionFactory(new SQLiteConnectionFactory());
SetProviderFactory("System.Data.SQLite", SQLiteFactory.Instance);
SetProviderFactory("System.Data.SQLite.EF6", SQLiteProviderFactory.Instance);
Type t = Type.GetType( "System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6");
FieldInfo fi = t.GetField("Instance", BindingFlags.NonPublic | BindingFlags.Static);
SetProviderServices("System.Data.SQLite", (DbProviderServices)fi.GetValue(null));
}
}