2010-12-03 40 views
1

我需要从我的c#应用程序运行一个文件中的sql脚本。 问题是它在不同的数据库上创建一个执行命令的对象。C#SQL Server脚本更改数据库问题

在脚本,每次我需要改变它使用的命令

USE [databasename]

,并因为有许多对象创建它使用命令GO了很多次了当前数据库的时间,所以我读该文件,直到我找到一个GO命令并在数据库中运行该句子;到目前为止这么好,但是在命令运行之后,连接返回到默认数据库(在这种情况下是master),忽略最后一个USE语句。

这是我用来读取文件并执行脚本的代码。

using (StreamReader reader = new StreamReader(databaseScriptFile)) 
    { 
     DatabaseFactory.CreateDatabase() 
     Database db = new SqlDatabase(connectionstring); 
     txbuilder = new StringBuilder(); 
     bool lastExecute = true;    
     while (!reader.EndOfStream) 
     { 
      text = reader.ReadLine(); 
      if (text.Trim().ToUpper() != "GO") 
      { 
       lastExecute = false; 
       txbuilder.AppendLine(text); 
      } 
      else 
      { 
       lastExecute = true; 
       db.ExecuteNonQuery(CommandType.Text, txbuilder.ToString()); 
       txbuilder.Length = 0; 
      } 
     } 
     //Make sure that the last sentence is executed 
     if (!lastExecute) 
      db.ExecuteNonQuery(CommandType.Text, txbuilder.ToString()); 
    } 

看来,它会清除各的ExecuteNonQuery命令执行后sp_reset_conection的连接(这是我在探查获得)

是否有acomplish这个任何优雅和简单的方法?

感谢

+0

这与'Enterprise-Library'有什么关系? – 2010-12-03 23:59:43

回答

2

有与测试工具,并在自己的博客结果good investigation by Joshua Flanagan。它看起来好像他遇到了类似的问题。

有两种方法可以做到这一点,您必须评估哪种方法最适合您,以及是否有任何连锁效应。

  1. 明确地打开和关闭数据库连接。因此,您不必仅仅使用SqlDatabase打开数据库,您需要创建一个SqlConnection并在其上调用Open()
  2. 只需将Connection Reset=False添加到您的连接字符串。我不知道这种方法的优缺点,所以不知道是否有任何副作用,因为我知道这可以禁用连接池。在应用程序/实用程序的环境中,你会比我更了解。

我建议阅读the blog article了解所有的血淋淋的细节,然后做一点点的挖掘,看看哪些是最适合你的。

2

我会说解析出USE [数据库]并存储它。然后将它添加到每个新的查询字符串的开头,一旦它们全部放在一起。像这样:

using (StreamReader reader = new StreamReader(databaseScriptFile)) 
     { 
      DatabaseFactory.CreateDatabase(); 
      Database db = new SqlDatabase(connectionstring); 
      txbuilder = new StringBuilder(); 
      bool lastExecute = true; 
      string useDB = ""; 
      while (!reader.EndOfStream) 
      { 
       text = reader.ReadLine(); 
       if (text.Substring(0, 3) == "USE") 
       { 
        useDB = text; 
       } 
       else if (text.Trim().ToUpper() != "GO") 
       { 
        lastExecute = false; 
        txbuilder.AppendLine(text); 
       } 
       else 
       { 
        lastExecute = true; 
        strQuery = useDB + txbuilder.ToString(); 
        db.ExecuteNonQuery(CommandType.Text, strQuery); 
        txbuilder.Length = 0; 
       } 
      } 
      //Make sure that the last sentence is executed 
      if (!lastExecute) 
       db.ExecuteNonQuery(CommandType.Text, txbuilder.ToString()); 
     } 

注意,如果该行是一个USE [数据库名称],它把它在useDB,并没有将它添加到您的txbuilder变量。所以,每次你填充txbuilder时,你都会将useDB和它一起附加到strQuery中,然后运行查询。然后每个查询以“USE [databasename]”开头......

此外,每当您点击一个新的USE时,它都会切换到使用该数据库。