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

时间:2013-10-24 14:05:09

标签: c# sql-server entity-framework sqlite

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

到目前为止,我已经通过连接到MS Server数据库并添加了我的单个测试表(称为Contact)来创建我的.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”。

我试图找到解决方案,但已经走到了尽头,我正在努力寻找下一步。

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


以上异常的堆栈跟踪:

  

在System.Data.SqlClient.SqlCommand.set_DbConnection(DbConnection   价值)   System.Data.Common.Utils.CommandHelper.SetStoreProviderCommandState(EntityCommand   entityCommand,EntityTransaction entityTransaction,DbCommand   storeProviderCommand)at   System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand   entityCommand,CommandBehavior behavior)at   System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute [TResultType](ObjectContext的   context,ObjectParameterCollection parameterValues)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()   在c:\ Development \ Projects \ Test中的SQLiteTest.Program.ReadFromSqlite()中   Applications \ SQLiteTest \ SQLiteTest \ Program.cs:第82行   cite:Projects \ Projects \ Test中的SQLiteTest.Program.ReadTests()   Applications \ SQLiteTest \ SQLiteTest \ Program.cs:第63行   c:\ Development \ Projects \ Test中的SQLiteTest.Program.ProcessMenu()   Applications \ SQLiteTest \ SQLiteTest \ Program.cs:第36行   cite:Projects \ Projects \ Test中的SQLiteTest.Program.Main(String [] args)   Applications \ SQLiteTest \ SQLiteTest \ Program.cs:第14行   System.AppDomain._nExecuteAssembly(RuntimeAssembly程序集,String []   args)at   Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
  在System.Threading.ExecutionContext.RunInternal(ExecutionContext   executionContext,ContextCallback回调,对象状态,布尔值   preserveSyncCtx)at   System.Threading.ExecutionContext.Run(执行上下文   executionContext,ContextCallback回调,对象状态,布尔值   preserveSyncCtx)at   System.Threading.ExecutionContext.Run(执行上下文   executionContext,ContextCallback回调,对象状态)at   System.Threading.ThreadHelper.ThreadStart()

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

您可以使用Entity Framework Code First轻松实现这一目标。代码优先方法不使用.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 Code FirstEF 6 Code First