【问题标题】:MVC create SQL database using SMOLiteMVC 使用 SMOLite 创建 SQL 数据库
【发布时间】:2012-04-14 03:32:16
【问题描述】:

我正在尝试使用自定义操作从 Visual Studio 2010 Web 设置项目创建一个新数据库。 首先,我做了一个 From 用户选择他们的 sql 服务器的名称和身份验证模式的地方。我使用以下命令获取服务器名称:

public string ServerString { get; set; }
   private void SetServerString()
        {
            string cs;
            if (cbInstant.SelectedIndex == 0) // windows authentication
                cs = cbServer.SelectedValue.ToString();
            else
                cs = string.Format(cbServer.SelectedValue + ";" + txtUser.Text + ";" + txtPassword.Text);

            ServerString = cs;
        }

        private void btnNext_Click(object sender, EventArgs e)
        {
              SetServerString();
              formContext.Parameters["ServerString"] = this.ServerString;
              this.Close();
        }

它运行良好,例如“PCName\SQLEXPRESS”。

在自定义操作中:

public override void Install(System.Collections.IDictionary stateSaver)
        {
  string serverString = "";
            if (this.Context.Parameters["ServerString"] != null)
                serverString = this.Context.Parameters["ServerString"];
 base.Install(stateSaver);
            MakeSQLDatabase(connectionString);
}
   private void MakeSQLDatabase(string serverString)
        {
            FileInfo file = new FileInfo("M:\\script.sql");
            string script = file.OpenText().ReadToEnd();
            file.OpenText().Close();
            SqlConnection sqlConnection = new SqlConnection();
            SqlConnectionStringBuilder sqlConnectionStringBuilder = new SqlConnectionStringBuilder();
            sqlConnection.ConnectionString = sqlConnectionStringBuilder.ToString();
            Server server = new Server(sqlConnection);
            server.ConnectionContext.ServerInstance = (serverString);
            server.ConnectionContext.Connect();
            if (server.Databases["databasename"] != null)
            {
                server.KillAllProcesses("databasename");
                server.KillDatabase("databasename");
            }
            Database database = new Database(server, "databasename");
            database.Create();
            database.ExecuteNonQuery(script);
        }

我收到一个错误“服务器未找到或无法访问”,但是如果我将变量 serverString 更改为

@"PCName\SQLEXPRESS"

有效!!我不知道是什么问题。我无法使用 Microsoft.SqlServer.Management.Smo,因为版本 2 和版本 4 之间存在冲突。即使添加了 app.confg

<?xml version="1.0"?>
<configuration>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

非常感谢您的帮助,或者您能否指导我找到更好的解决方案来完成此任务。提前致谢。

【问题讨论】:

    标签: c# sql-server asp.net-mvc smo


    【解决方案1】:

    我不明白,你想用 .NET 2 而不是 .NET 4 创建一个新数据库?我为此使用了 SMO,但也会尝试 :) Atm 我只是将主数据库连接到使用 SQL 来完成“CREATE DATABASE”的工作。只要您与“主”数据库建立有效连接,此方法就可以工作。

    更新:

    var sql = "";
    using (var cnn = new SqlConnection(connection))
    {
      cnn.Open();
      sql = "CREATE DATABSE <databasename>";
      using (var cmd = new SqlCommand(sql, cnn))
      {
        try
        {
          cmd.CommandTimeout = 120;
          cmd.ExecuteNonQuery();
        }
        catch (Exception ex)
        {
          Console.WriteLine("Execution error!\n\n" + sql + "\n\n\n" + ex);
        }
      }
      sql = "USE DATABSE <databasename>;EXEC sp_dbchangeowner <Username>";
      using (var cmd = new SqlCommand(sql, cnn))
      {
        try
        {
          cmd.CommandTimeout = 120;
          cmd.ExecuteNonQuery();
        }
        catch (Exception ex)
        {
          Console.WriteLine("Execution error!\n\n" + sql + "\n\n\n" + ex);
        }
      }
      cnn.Close();
    }
    

    连接必须是与“主”数据库的连接。 并且需要更换。 如果你想这样做动态,那么像:

    sql = string.Format("USE DATABSE {0};EXEC sp_dbchangeowner {1}",database,username);
    

    您使用数据库名称“master”与您已有的函数设置的连接。 然后你就完成了,可以像这样设置任何数据库了。

    要检查 SQL 中的帮助,您可以在您的第一个 SQL 中添加:

    IF ( (SELECT IsNull(db_id('latest'),-1) )>0 )
    

    希望这会有所帮助。我不知道这是否是最聪明的方式,但在这种情况下,我可以简单地连接,然后创建、更改等任何我想要的东西。 在我的例子中,我完全创建了一个数据库,使用 stringbuilder 加载一堆 sql 命令并针对新数据库执行所有 CREATE table/column/query 语句。 删除 DB 是一个简单的“DROP DATABASE”。

    【讨论】:

    • 这是一个用于安装 4.0 应用程序的网络设置应用程序。我有两个选择,使用 SMO 或 SMOLite!。如果您能与我分享您是如何连接到服务器并创建数据库的,我将不胜感激。谢谢
    • 是你的示例的第一行 var sql 0 "";我收到错误,这不是一个有效的声明。谢谢
    • 谢谢,有趣的方法;我将重新设计我的脚本。
    • 从文件运行 sql 时出现与 GO 相关的错误。我找到了这个解决方案*.com/questions/650098/…,效果很好。再次感谢 YvesR。
    • @user373721 如果您在一个文件中有很多 SQL 命令:全部读取它们,然后使用 GO 作为分隔符将它们拆分,然后执行 foreach 循环。在这种情况下,您可以执行每个命令并写入日志,哪些 sql 命令成功,哪些失败。这就是我所做的,但我在此示例中删除了该代码 sn-ps。