我正在尝试生成一些代码,检查我的SQL服务器是否可连接。并且:如果是这样,那么它应该检查数据库是否存在。 让我通过代码解释一下。
这是我的主要方法:
private static void Main(string[] args)
{
Database.SetInitializer<MyDbContext>(new DropCreateDatabaseAlways<MyDbContext>());
Console.WriteLine(CheckIfDatabaseExists("Data Source=127.0.0.1\\SQLEXPRESS2;Initial Catalog=SQLTest;Integrated Security=True;Connect Timeout=3"));
Console.WriteLine(CheckIfDatabaseExists("Data Source=127.0.0.1\\SQLEXPRESS;Initial Catalog=SQLTest;Integrated Security=True;Connect Timeout=3"));
Console.WriteLine(CheckIfDatabaseExists("Data Source=127.0.0.1\\SQLEXPRESS2;Initial Catalog=SQLTest;Integrated Security=True;Connect Timeout=3"));
}
您可以想象:我的本地SQL服务器'SQLEXPRESS'上存在一个现有数据库'SQLTest'。 但是:没有像'SQLEXPRESS2'这样的服务器!
好的 - 更多代码。这是我的检查方法:
public static DatabaseExistsStatus CheckIfDatabaseExists(String connString)
{
try
{
using (var db = new MyDbContext(connString))
{
bool DbExists = db.Database.Exists();
if (DbExists)
{
// database is existing
return DatabaseExistsStatus.EXISTING;
}
else
{
// config is working, but database does not exist
return DatabaseExistsStatus.NO_DB;
}
}
}
catch (Exception)
{
// no working config
return DatabaseExistsStatus.NO_CONNECTION;
}
}
public enum DatabaseExistsStatus
{
EXISTING,
NO_CONNECTION,
NO_DB
}
启动我的应用会带来以下结果:
NO_CONNECTION
EXISTING
NO_DB
我很困惑!我期待“NO_CONNECTION,EXISTING,NO_CONNECTION”。
就是这样!我不知道后台发生了什么,以及如何控制。
那里发生了什么,我该如何解决?
答案 0 :(得分:0)
这是我认为的一种预期行为(至少部分),据我所知(并且没有进入反射器)
看看有关如何初始化DbContext的详尽说明Code First: Inside DbContext Initialization
简化了一点 - DbContext
不会为每个new DbContext
重新创建内容。在内部,EDM(实体数据模型)和其他一些东西(一个'真正的'ObjectContext
实例)被缓存为AppDomain
。
在这种特殊情况下,第一次调用没有做任何事情,它无法定位服务器并且没有“可行的”替代方案 - 所以它只是出错 - 而且你得到'没有连接'。
在下一个传递中,它成功并初始化了一些内部数据(对于AppDomain来说是'全局' - 在大多数情况下意味着你的应用程序) - 非常“new DbContext
”几乎没有任何数据,但在首先使用,在你的情况下,'Exists
'它不会创建Db但会进行一些初始化(看似)。
在最后一次传递中,它尝试打开连接,失败 - 但它已经有一个有效的连接,可以从它已经初始化的数据中重用。
唯一的问题是为什么它会'继续''失败'连接尝试并重复使用旧连接(因为它是一个明确的调用),我没有答案 - 但它是它看起来的样子(并且它是内部实现 - 还是一个bug?)。
答案 1 :(得分:0)
您可以使用此代码控制连接状态
var db = new MyDbContext(connString));
if (db.Database.Connection.State == System.Data.ConnectionState.Open)
{
// do something
}