我有一个问题,我现在已经打了一段时间了,而且我希望有人比我更了解这个问题。
我的部分应用程序使用传统的System.Data.SqlClient内容连接到一个数据库,另一部分使用Entity Framework使用这两个连接字符串连接到同一SQL服务器上的不同数据库:
var connectionString =
"Server=SERVER\SQLEXPRESS;Database=Database1;User=myUser;Password=myPass;";
var efConnectionString =
"Server=SERVER\SQLEXPRESS;Database=Database2;User=myUser;Password=myPass;";
使用我的应用程序的非EF部分,我可以很好地访问数据库。但是当我尝试对EF部分做任何事情时,我得到一个例外,说它无法找到SQL Server实例:
System.Data.SqlClient.SqlException(0x80131904):建立与SQL Server的连接时发生与网络相关或特定于实例的错误。服务器未找到或无法访问。验证实例名称是否正确,以及SQL Server是否配置为允许远程连接。 (提供程序:SQL网络接口,错误:26 - 查找指定的服务器/实例时出错)
我已经三次检查EF连接字符串中没有拼写错误,甚至有几位同事重新检查它。我还检查了context.Database.Connection.ConnectionString
属性以确保它使用正确的连接字符串,它是。
这真的没有任何意义。什么会导致EF在我尝试过的其他方法都找不到SQL Server?
我的上下文如下:
public class MyContext : DbContext
{
public MyContext() { }
public MyContext(string connString) : base(connString) { }
...
}
我总是使用接受连接字符串的重载构造函数构造:
var context = new MyContext(efConnectionString);
我甚至删除了默认构造函数并构建了项目,以确保它不会在其他任何地方使用。
答案 0 :(得分:3)
终于找到了问题!
我在这个应用程序中首先使用代码。在启动代码中,我将初始化程序设置为新的MigrateDatabaseToLatestVersion
初始化程序:
Database.SetInitializer<MyContext>(
new MigrateDatabaseToLatestVersion<MyContext, Migrations.Configuration>());
初始化数据库时,它使用默认构造函数实例化新的MyContext
。所以它试图连接到我的服务器上不存在的默认SQL实例(LocalDb或SQLExpress)。
如果我想使用具有正确连接字符串的上下文,我可以在MigrateDatabaseToLatestVersion
的构造函数中告诉它:
Database.SetInitializer<MyContext>(
new MigrateDatabaseToLatestVersion<MyContext, Migrations.Configuration>(
useSuppliedContext: true));
这对我来说似乎应该是默认行为。为什么初始化程序需要创建一个新的上下文,如果它在运行时提供了一个新的上下文?哦,好吧。
答案 1 :(得分:1)
这可能是您构建Entity Framework上下文的方式中的一个问题。 DbContext
的构造函数有一个带有nameOrConnectionString
的重载,可以通过配置的<connectionStrings>
元素或完整的连接字符串提供连接的名称。还有一个默认构造函数,如果您使用它,它将使用约定来查找数据库。我认为在LocalDb(而不是SQLExpress)中查找与DbContext派生类名称相同的数据库。