Подтвердить что ты не робот

Проблемы с использованием 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 снова и снова и т.д.

Я не знаю, куда идти отсюда.

4b9b3361

Ответ 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));
    }
}