使用entity framework6和SQLite的问题
我试图用SQLite的entity framework。 我有问题集成到我的主要应用程序,所以我从头开始一个小testing,完全按照http://brice-lambson.blogspot.com/2012/10/entity-framework-on-sqlite.html
毕竟说完了,运行项目时出现以下错误:
找不到名称为“System.Data.SQLite”的ADO.NET提供程序的entity framework提供程序。 确保提供程序在应用程序configuration文件的“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>
然后,我看到他的post关于entity framework6.虽然这不是我得到的确切的错误,我尝试通过NuGet安装他的更新的提供者。 错误消失了,但换成了这个:
无法加载文件或程序集“System.Data.SQLite.Linq,Version = 2.0.88.0,Culture = neutral,PublicKeyToken = db937bc2d44ff139”或其某个依赖项。 定位的程序集清单定义与程序集引用不匹配。 (来自HRESULT的exception: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包等。
我不知道该从哪里出发。
只是想我会分享另一种方式来configurationEF6与SQLite,而不使用app.config
/ web.config
。 EF6现在支持基于代码的configuration,如msdn上所述 。 我使用下面的代码(更新,以消除reflection感谢狡猾):
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
,不需要在主程序集中configuration的所有东西。
编辑:
正如Reyn所说 ,如果你希望在你的web.config
/ app.config
文件中有连接string,你还需要为SQLite添加一个IDbConnectionFactory
。 另一种方法是从你的DbContext
调用一个不同的基础构造函数,它传入一个新的SQLiteConnection
而不是连接string, 如此答案所示。
基于magicandre1981的评论,我开始更加关注提供者节点的语法。 我发现我的程序集与type属性中指定的版本不同,尽pipe我没有插入或触摸特定的行。 通过删除强命名,我得到.Net加载图书馆。 作为参考,这里是新的一行:
<provider invariantName="System.Data.SQLite" type="System.Data.SQLite.SQLiteProviderServices, System.Data.SQLite.Linq" />
这使我回到正轨,我能够将我的结果与博客上的结果相匹配。
然而,我感到不得不指出,我已经决定SQLite不适合entity framework,因为太多的关键function缺失。 我切换到通过NuGet安装的SQL Server Compact Edition。 对我的连接string进行简单的调整,并且使用Entity Framework的全部function运行。 花了不到一分钟的时间,与SQLite的多小时博客相比。 我build议如果可能的话切换数据库,System.Data.SQLite只是没有准备好entity framework。
我知道这是一个老问题,但似乎没有人提供实际使用.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>
对于任何人使用基于代码的设置,仍然得到相同的exception:我需要另外设置连接工厂在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)); } }