我有这样的代码:
using (var sqlConnection = new SqlConnection(connectionString))
{
sqlConnection.Open();
using (var sqlCommand = new SqlCommand(scriptText, sqlConnection))
{
sqlCommand.ExecuteNonQuery();
}
}
我第一次调用它来创建一个数据库,然后我形成一个连接字符串到这个数据库并尝试做一些工作(Open
工作正常并说连接实际上是为第二个连接打开的) 。但我得到一个“现有连接被远程主机强行关闭”,我可以看到sql日志“无法找到数据库ID 9.数据库可能尚未激活或可能正在转换”。所以,实际上在作业完成之前ExecuteNonQuery
返回。当然,我可以直接将其发送垃圾邮件,直到情况发生变化,但还有更好的方法可以让DB为工作做好准备吗?
答案 0 :(得分:3)
这个完整的样本适合我。
它创建数据库,创建表,在表中放置一行。
不确定你的结果有什么问题。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
namespace GranadaCoder.PlaygroundConsole.SqlStuff
{
public class SqlPlayground
{
public static void EntryPointStuff()
{
string databaseName = "MyFirstDatabaseABC";
string connectionString = string.Empty;
string commandText = string.Empty;
int returnValue = 0;
string msg = string.Empty;
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
builder["Initial Catalog"] = "master";
builder["integrated Security"] = true;
builder["Server"] = @"MyMachine\MyInstance";
connectionString = builder.ConnectionString;
commandText = string.Format("IF EXISTS (Select * from sys.databases where name = N'{0}') DROP DATABASE [{0}]", databaseName);
returnValue = RunACommand(connectionString, commandText);
msg = string.Format("'{0}', {1}", returnValue, commandText);
Console.WriteLine(msg);
commandText = string.Format("IF NOT EXISTS (Select * from sys.databases where name = N'{0}') CREATE DATABASE [{0}]", databaseName);
returnValue = RunACommand(connectionString, commandText);
msg = string.Format("'{0}', {1}", returnValue, commandText);
Console.WriteLine(msg);
/* Change the Catalog */
builder["Initial Catalog"] = databaseName;
connectionString = builder.ConnectionString;
commandText = "if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[CodeCategory]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) BEGIN DROP TABLE [dbo].[CodeCategory] END ";
returnValue = RunACommand(connectionString, commandText);
msg = string.Format("'{0}', {1}", returnValue, commandText);
Console.WriteLine(msg);
commandText = "CREATE TABLE [dbo].[CodeCategory] ( CodeCategoryKey [smallint] not null , CodeCategoryName varchar(64) not null ) ";
returnValue = RunACommand(connectionString, commandText);
msg = string.Format("'{0}', {1}", returnValue, commandText);
Console.WriteLine(msg);
commandText = "INSERT INTO [dbo].[CodeCategory] ( CodeCategoryKey , CodeCategoryName ) Select 1001 , 'MyFirstCodeCategory' ";
returnValue = RunACommand(connectionString, commandText);
msg = string.Format("'{0}', {1}", returnValue, commandText);
Console.WriteLine(msg);
commandText = "Select Count(*) from [dbo].[CodeCategory]";
returnValue = RunACommand(connectionString, commandText);
msg = string.Format("'{0}', {1}", returnValue, commandText);
Console.WriteLine(msg);
}
private static int RunACommand(string connectionString, string scriptText)
{
int returnValue = 0;
using (var sqlConnection = new SqlConnection(connectionString))
{
sqlConnection.Open();
using (var sqlCommand = new SqlCommand(scriptText, sqlConnection))
{
returnValue = sqlCommand.ExecuteNonQuery();
}
sqlConnection.Close();
}
return returnValue;
}
}
}
这对我有用(没有例外):
static void Main(string[] args)
{
try
{
SqlPlayground.EntryPointStuff();
Console.WriteLine("Press Enter after deleting the database in SSMS manually with 'Close Existing Connections' checked.");
Console.ReadLine();
SqlPlayground.EntryPointStuff();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("Pressing Enter To End");
Console.ReadLine();
}
答案 1 :(得分:0)
如果您在创建后立即执行其他操作(例如更新数据库架构),您可能会注意到此问题。等待几秒似乎解决了这个问题。
//wait for database creation
Thread.Sleep(3000);
答案 2 :(得分:0)
在我的情况下adding Thread.Sleep(...)有帮助,但 root 的原因是失败的连接被缓存并由方法SqlConnection.Open()使用。有关此情况,请参阅answer for this question。 Clearing the pool with SqlConnection.ClearAllPools()有帮助。
为什么等待几秒钟也有帮助呢?似乎它足以通过计时器自动清除池。