【发布时间】:2015-07-01 23:12:42
【问题描述】:
我正在开发一个应用程序,其中最终用户在运行时选择数据库。该数据库可以位于 MS SQL 服务器或 IBM DB2 服务器上。我目前在 Windows 服务器上使用 IBM DB2 10 Express-c 进行测试。我正在使用 Visual Studio 2013 C# 和 Entity Framework 6 进行开发。我已经安装了 EntityFramework.IBM.DB2 Nuget 包以支持 DB2。我对现有的 SQL 服务器数据库使用逆向工程代码优先来生成我的基本代码。该应用程序适用于 SQL Server 数据库。
我正在使用 System.Data.Common.DbProviderFactories.GetFactory 来生成提供程序。
System.Data.EntityClient.EntityConnectionStringBuilder connectString = new System.Data.EntityClient.EntityConnectionStringBuilder(a_Connection);
System.Data.Common.DbConnection conn = System.Data.Common.DbProviderFactories.GetFactory(connectString.Provider).CreateConnection();
conn.ConnectionString = connectString.ProviderConnectionString;
LB500Database = new LB402_TestContext(conn, true);
a_Connection is provider=IBM.Data.DB2;provider connection string="Database=LISTBILL;User ID=xxxx;Password=yyyy;Server=db210:50000" 并被 EntityConnectionStringBuilder 正确解析。
然后我尝试使用
访问数据库中的表 LBData500.LB_System oneSystem;
System.Linq.IQueryable<LB_System> allSystem = LB500Database.LB_System.Where(g => g.DatabaseVersion == databaseVersion && g.CompanyID == companyID);
我得到一个无效的操作异常“序列不包含匹配的元素”,这意味着没有返回任何元素。如果我删除 Where 以便返回所有行(表中有一个)并尝试使用 VS 调试器枚举结果集,我会看到以下消息: “在创建模型时不能使用上下文。如果在 OnModelCreating 方法中使用上下文或多个线程同时访问同一个上下文实例,则可能会引发此异常。请注意,DbContext 和相关类的实例成员是不保证是线程安全的。”
我没有使用多线程。我不在 OnModelCreating 里面。
只需将连接字符串更改为指向 SQL 服务器就可以了,所以我认为我的基本方法是合理的。如果我从服务器收到某种错误,我将有一些事情要做。我可以从 Visual Studio 内部运行查询,所以我有连接性。
任何指针将不胜感激。
更新: 我发现 EF 对象是使用 EF5 生成的,并且正在使用 EF6 运行时。我首先使用 EF6 逆向工程代码重新生成了 EF 对象。我现在可以连接到数据库并收到一条错误消息: “错误 [42704] [IBM][DB2/NT64] SQL0204N \"DBO.LB_SYSTEM\" 是一个未定义的名称。” DB2 数据库中的模式与我的用户标识相同(在这种情况下,并非总是如此)。我在提供的连接字符串中添加了 CurrentSchema=xxxx,但 EF 仍在传递 dbo 作为架构名称。
现在我需要一种在运行时更改架构名称的方法。我看到了 codeplex EFModelAdapter (http://efmodeladapter.codeplex.com) 的链接。所以我可以试试看。
Update2 在浏览了 EFModelAdapter 之后,我决定采取不同的路线。由于我只需要数据库访问而不是模式管理,因此我决定使用 Dapper (https://github.com/StackExchange/dapper-dot-net)。这非常适合我的需要,并允许我在访问 DB2 数据库时更改模式名称。
【问题讨论】:
标签: entity-framework db2 entity-framework-6