同时将实体框架与 SQL Server 和 SQLite 数据库一起使用

本文关键字:SQLite 数据库 一起 Server SQL 实体 框架 | 更新日期: 2023-09-27 18:36:39

我有一个用于测试目的的 C# .Net 4.0 控制台应用程序(使用 VS 2012)。我的目标是能够创建一个可以在MS SQL Server数据库和SQLite数据库上使用的单个实体框架.edmx文件。基本上,我想使用相同的实体模型类和集合进行查询,但可以轻松地随意在两个不同的数据库之间切换。

到目前为止,我已经通过连接到MS Server数据库并添加我的单个测试表(称为联系人)创建了.edmx文件。有了这个,我可以使用以下代码从我的表中获取数据:

var db = new DataAccess.ContactTestEntities();
foreach (var contact in db.Contacts)
    Console.WriteLine("" + contact.ID + ". " + contact.FirstName + " " + contact.LastName);

现在,我希望能够使用相同的代码,但改为连接到SQLite数据库。我编写了一个分部类,允许我在构造上更改连接字符串,如下所示:

var db = new DataAccess.ContactTestEntities("MY SQLITE CONNECTION STRING");

它在这方面工作正常,除非在尝试查询数据库时出现此错误:

无法将类型为"System.Data.SQLite.SQLiteConnection"的对象转换为类型"System.Data.SqlClient.SqlConnection"。

试图找到解决方案,但陷入了死胡同,我正在努力寻找下一步。

这就是我的问题:我怎样才能克服这个问题?或者我可以采取另一种方法来获得相同的预期结果?


上述异常的堆栈跟踪:

at System.Data.SqlClient.SqlCommand.set_DbConnection(DbConnection 值)在 System.Data.Common.Utils.CommandHelper.SetStoreProviderCommandState(EntityCommand entityCommand, EntityTransaction entityTransaction, DbCommand storeProviderCommand) at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommand(EntityCommand entityCommand, CommandBehavior behavior) at System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext 上下文, 对象参数集合参数值) at System.Data.Objects.ObjectQuery 1.GetResults(Nullable 1 forMergeOption) at System.Data.Objects.ObjectQuery 1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() at System.Data.Entity.Internal.Linq.InternalQuery 1.GetEnumerator()
at System.Data.Entity.Internal.Linq.InternalSet 1.GetEnumerator()
at System.Data.Entity.Infrastructure.DbQuery
1.System.Collections.Generic.IEnumerable.GetEnumerator() at SQLiteTest.Program.ReadFromSqlite() in c:''Development''Projects''Test Applications''SQLiteTest''SQLiteTest''Program.cs:line 82 at SQLiteTest.Program.ReadTests() in c:''Development''Projects''Test Applications''SQLiteTest''SQLiteTest''Program.cs:line 63 at SQLiteTest.Program.ProcessMenu() in c:''Development''Projects''Test Applications''SQLiteTest''SQLiteTest''Program.cs:line 36 at SQLiteTest.Program.Main(String[] args) in c:''Development''Projects''Test Applications''SQLiteTest''SQLiteTest''Program.cs:line 14 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] 参数)在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()

同时将实体框架与 SQL Server 和 SQLite 数据库一起使用

使用 sqlite dbcontext 为 dbcontext 对象创建另一个类,并使用相同的模型类。 原因很简单,默认实体适用于 sqlserver db。要使用 sqlite,您必须使用 sqlite dbcontext。

是否在"<connectionStrings>应用设置"部分中传入连接字符串或连接字符串的名称? 我相信问题正如你所描述的那样。 它将提供程序默认为 System.Data.SqlClient。 如果你想要 Sql Lite,你必须在<connectionString>上设置 providerName,然后将该<connectionString>的名称(属性)发送到 DbContext(它知道如何自动查找)。 然后,它应使用该新的提供程序名称属性,而不是 SqlClient。

可以使用实体框架代码优先轻松实现此目的。代码优先方法不使用 .edmx 文件。您的实体(类)会自动映射到数据库表。

您将在 app.config 文件中定义这两个connectionstring配置它们的提供程序。现在,您可以通过将所需的connectionstring传递给 EF 来在数据库之间切换。

/* connection string for SQLite */
<add name="SQLiteConnection" connectionString="Data Source=MyDBName.sqlite" providerName="System.Data.SQLite" />
/* connection string for SQL Server */
<add name="SQLServerConnection" connectionString="Data Source=MyDB; Integrated Security=True" providerName="System.Data.SqlClient" />

有关详细信息,请参阅 SQLite 代码优先和 EF 6 代码优先。