我正在开发一个应用程序,最终用户在运行时选择数据库。数据库可以位于MS SQL服务器上,也可以位于IBM DB2服务器上。我目前正在Windows服务器上使用IBM DB2 10 Express-c进行测试。我正在使用Visual Studio 2013 C#和Entity Framework 6进行开发。我已经为DB2支持安装了EntityFramework.IBM.DB2 Nuget包。我正在使用反向工程代码优先对现有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是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);
我得到一个无效的操作异常“Sequence包含没有匹配的元素”,这意味着不返回任何元素。如果我删除Where以便返回所有行(表中有一个)并尝试使用VS调试器枚举结果集,我会看到以下消息: “在创建模型时不能使用上下文。如果在OnModelCreating方法中使用上下文,或者同时由多个线程访问相同的上下文实例,则可能抛出此异常。请注意,DbContext和相关类的实例成员是不保证是线程安全的。“
我没有使用多线程。我不在OnModelCreating中。
只需将连接字符串更改为指向SQL服务器就可以正常工作,所以我认为我的基本方法是合理的。如果我从服务器收到某种错误,我会有一些事情要继续。我可以从Visual Studio内部运行查询,因此我可以连接。
任何指针都会受到赞赏。
更新 我发现EF对象是使用EF5生成的,并且正在使用EF6运行时。我首先使用EF6逆向工程代码重新生成EF对象。我现在可以连接到数据库并收到错误消息: “ERROR [42704] [IBM] [DB2 / NT64] SQL0204N \”DBO.LB_SYSTEM \“是一个未定义的名称。” DB2数据库中的模式与我的userid相同(在这种情况下,并非总是如此)。我将CurrentSchema = xxxx添加到提供连接字符串,但EF仍然将dbo作为模式名称传递。
现在我需要一种在运行时更改架构名称的方法。我看到了codeplex EFModelAdapter(http://efmodeladapter.codeplex.com)的链接。所以我可以尝试一下。
Update2 在浏览EFModelAdapter之后,我决定采用不同的路线。由于我只需要数据库访问而不需要模式管理,所以我决定选择Dapper(https://github.com/StackExchange/dapper-dot-net)。这非常适合我的需要,并允许我在访问DB2数据库时更改模式名称。
答案 0 :(得分:0)
根据我的更新2,实体框架对我所需要的东西有点过分。我切换到了精致https://github.com/StackExchange/dapper-dot-net,我在多个DBMS上工作正常。