簡體   English   中英

使用Entity Framework 6和SQLite的問題

[英]Problems using Entity Framework 6 and SQLite

我正在嘗試使用SQLite實體框架。 我將問題集成到我的主應用程序中時遇到了問題,因此我從頭開始進行了一些測試,完全按照http://brice-lambson.blogspot.com/2012/10/entity-framework-on-sqlite.html上的說明進行操作。

畢竟說完了,運行項目時出現以下錯誤:

沒有為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>

然后我看到他關於實體框架6的帖子。雖然這不是我得到的確切錯誤,但我嘗試通過NuGet安裝他更新的提供程序。 錯誤消失了,但取而代之的是:

無法加載文件或程序集'System.Data.SQLite.Linq,Version = 2.0.88.0,Culture = neutral,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包等。

我不知道從哪里開始。

我以為我會分享另一種方法,在不使用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)));
    }
}

我使用這個,所以我可以在運行時注入正確的DbContextDbProvider ,並且不需要在主程序集中配置的所有內容。

編輯:

正如Reyn所說 ,如果你希望在web.config / app.config文件中有你的連接字符串,你還需要為SQLite添加一個IDbConnectionFactory 另一種方法是從DbContext調用另一個基本構造函數,該構造函數傳遞新的SQLiteConnection而不是連接字符串,如本答案所示。

我知道這是一個老問題,但似乎沒有人提供實際使用.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>

根據magicandre1981的評論,我開始更仔細地研究提供者節點的語法。 我發現我的程序集與type屬性中指定的版本不同,但我沒有插入或觸摸該特定行。 通過刪除強命名,我得到.Net來加載庫。 作為參考,這是新行:

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

這讓我重回正軌,我能夠將我的結果與博客上的結果相匹配。

但是,我不得不注意到,我已經確定SQLite不適合實體框架,因為缺少太多關鍵功能。 我切換到我通過NuGet安裝的SQL Server Compact Edition。 對我的連接字符串的一個簡單調整,我正在運行Entity Framework的全部功能。 與SQLite的多小時口號相比,花了不到一分鍾。 我建議盡可能切換數據庫,System.Data.SQLite還沒有為Entity Framework做好准備。

對於任何使用基於代碼的設置並仍然得到相同異常的人:我需要在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));
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM