web-dev-qa-db-ja.com

Entity Framework 6とSQLiteの使用に関する問題

SQLiteでEntity Frameworkを使用しようとしています。メインアプリケーションに統合するのに問題があったので、 http://brice-lambson.blogspot.com/2012/10/entity-framework-on- sqlite.html

結局のところ、プロジェクトを実行すると次のエラーが表示されます。

不変名「System.Data.SQLite」を持つADO.NETプロバイダーのEntity Frameworkプロバイダーが見つかりません。プロバイダーがアプリケーション構成ファイルの「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、Version = 2.0.88.0、Culture = neutral、PublicKeyToken = db937bc2d44ff139」またはその依存関係の1つをロードできませんでした。検出されたアセンブリのマニフェスト定義は、アセンブリ参照と一致しません。 (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バイナリを使用してみました。 EFバージョン6を使用するようにSQLiteプロジェクトを手動で編集してみました。アーキテクチャを変更したり、何度も繰り返しNugetパッケージを追加したり削除したりしています。

ここからどこへ行くかわからない。

42
Xcelled

Magicandre1981のコメントに基づいて、プロバイダーノードの構文をより詳しく調べ始めました。アセンブリはtype属性で指定されたものとは異なるバージョンであることがわかりましたが、その特定の行を挿入したり触れたりしていませんでした。厳密な名前を削除することで、.Netにライブラリをロードさせることができました。参考のため、新しい行を次に示します。

<provider invariantName="System.Data.SQLite" type="System.Data.SQLite.SQLiteProviderServices, System.Data.SQLite.Linq" />

その結果、私は軌道に乗り、私の結果をブログの結果と一致させることができました。

ただし、SQLiteはEntity Frameworkに適さないと判断しました。重要な機能が多すぎるためです。 NuGetを介してインストールしたSQL Server Compact Editionに切り替えました。接続文字列を簡単に調整して、Entity Frameworkの全機能を使用して実行していました。 SQLiteであった数時間のスローと比較して、1分もかかりませんでした。可能であればデータベースを切り替えることをお勧めします。System.Data.SQLiteはEntity Frameworkに対応していません。

23
Xcelled

app.config/web.configを使用せずに、SQLiteでEF6を構成する別の方法を共有すると思いました。 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を注入でき、メインアセンブリですべてを構成する必要はありません。

編集:

Reyn氏 のように、web.config/app.configファイルに接続文字列を含める場合は、SQLiteのIDbConnectionFactoryも追加する必要があります。別のアプローチは、接続文字列ではなく、新しいDbContextを渡すSQLiteConnectionから異なるベースコンストラクターを呼び出すことです この回答では です。

55
kjbartel

これは古い質問であることは知っていますが、実際に.configファイルを使用する回答を提供した人はいないようです。以下は、web.configのsystem.dataおよびentityframeworkセクションで、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>
30
Clever Human

コードベースのセットアップを使用しても同じ例外が発生する場合:kjbartelの答えで接続ファクトリーを追加で設定する必要がありました。

public class SQLiteConnectionFactory : IDbConnectionFactory
{
    public DbConnection CreateConnection(string nameOrConnectionString)
    {
        return new SQLiteConnection(nameOrConnectionString);
    }
}

次に、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));
    }
}
15
Reyn