【问题标题】:How to build connection string from existing connection for new database created dynamically?如何从现有连接为动态创建的新数据库构建连接字符串?
【发布时间】:2017-12-30 06:52:52
【问题描述】:

我有查询动态创建数据库。

    private void ExecuteNonQuery(string sql)
    {
        using (var connection = new SqlConnection(_connectionString))
        {
            connection.Open();
            SqlCommand command = connection.CreateCommand();
            command.CommandText = sql;
            command.ExecuteNonQuery();
        }
    }

    private void CreateDatabase(string databaseName)
    {
        try
        {
            ExecuteNonQuery($"CREATE DATABASE {databaseName}");
        }
        catch (Exception e)
        {
            throw new Exception($"Can't create database '{databaseName}'");
        }
    }

数据库将使用我现有的连接创建,但我需要为这个新数据库创建连接字符串以运行迁移和用于各种其他目的。

这怎么可能?

更新

它实际上是为了让用户可以填写表格来创建一个新的数据库,在那里他们可以提供他们现有的连接字符串,或者如果他们手头没有连接字符串,我们会为他们构建它

【问题讨论】:

    标签: c# database entity-framework connection-string


    【解决方案1】:

    使用此函数获取到新数据库的连接:

    private SqlConnection NewDatebaseConnection(string databaseName)
        {
            SqlConnection  connection = new SqlConnection(_connectionString);
            connection.ChangeDatabase(databaseName);
            return SqlConnection;  
        }
    

    【讨论】:

    • 这不会解决我的问题。正如我在问题中所说,我需要连接字符串,以便可以将其保存在单独的文件中并重复使用。
    【解决方案2】:

    要保存新连接,您可以将ConnectionStringBuilder与现有连接一起使用,更改数据库名称并将其保存为app.config

    1.Helper方法获取连接字符串:

    string GetConnectionString(string name) =>
              ConfigurationManager.ConnectionStrings[name].ConnectionString;
    

    2.将新连接字符串保存到app.config的Helper方法:

    void CreateNewConnectionString(string baseName, string newName, string newDatabaseName)
    {
        // Get the connection string a new connection will be based on
        string baseConnString =
            ConfigurationManager.ConnectionStrings[baseName].ConnectionString;
        // For simplicity of manipulations with connection strings,
        // we use SqlConnectionStringBuilder, passing it an existing connection string
        var connBuilder = new SqlConnectionStringBuilder(baseConnString);
        // Change existing database name to the new database name
        connBuilder.InitialCatalog = newDatabaseName;
        // Create new settings, holding our new connection string
        var newConnection = new ConnectionStringSettings(newName, connBuilder.ToString());
        // Save new connection string
        var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        config.ConnectionStrings.ConnectionStrings.Add(newConnection);
        config.Save(ConfigurationSaveMode.Modified);
    }
    

    3.用法

    private void CreateDatabase(string databaseName)
    {
        try
        {
            // Create database using "main" connection string
            ExecuteNonQuery($"CREATE DATABASE {databaseName}", "main");
            // Create new connection string "my_db" based on "main"
            CreateNewConnectionString("main", "my_db", databaseName);
        }
        catch (Exception e)
        {
            throw new Exception($"Can't create database '{databaseName}'");
        }
    }
    

    【讨论】:

    • 一个疑问是,如果现有连接是带有 attacheFile mdf 的 LocalDB 怎么办?新数据库的附加文件路径是什么?
    • @Sachin 您可以在SqlConnectionStringBuilder 中设置和更改您需要的所有内容。而是基于现有连接的构建器,您可以从头开始创建自己的全新连接。所以,这不是问题:builder.AttachDBFilename.
    • 我实际上解决了连接字符串的格式可以根据提供者的权利而改变的问题,那么我们怎么能盲目地选择一种特定的格式呢?
    • 我已经完成了这些并且工作正常,但是我需要针对一般情况的解决方案?
    • @Sachin 那么,SqlConnectionStringBuilder 不适合你?
    【解决方案3】:

    如果您使用的是 EF,则应该有一个可以使用的上下文,如下所示:

    public class MyContext : DbContext
    {
        public MyContext():base("myConnectionStringName")
        {
        }
    }
    

    constructor 具有指定连接名称或连接字符串的参数。因此,您可以获得所需的任何连接字符串的上下文:

    using (var db = new MyContext("connection_string_containing_new_db") 
    {
        // do stuff with the context
    }
    

    您应该考虑使用构建此类上下文的工厂:

    class MyContextFactory
    {
        MyContext CreateContextForDatabase(string dbName) 
        {
             var builder = new SqlConnectionStringBuilder();
             builder["Data Source"] = "server\\instance";
             builder["integrated Security"] = true;
             builder["Initial Catalog"] = dbName;
    
             return new new MyContext(builder.ConnectionString);
        }
    }
    

    代码使用SqlConnectionStringBuilder 构造(从头开始)连接字符串。另一种方法是使用var builder = new SqlConnectionStringBuilder(staticConnectionString) 解析静态连接字符串,并且只更改Initial Catalog

    【讨论】:

    • :) 除了构建连接字符串的答案之外,您说了所有其他内容。如何使用 SqlConnectionStringBuilder 识别现有连接并相应地构建连接字符串?
    • @Sachin - 这是真的:)。我已经编辑了我的答案以显示如何构建连接字符串。
    • 我实际上解决了连接字符串的格式可以根据提供者的权利而改变的问题,那么我们怎么能盲目地选择一种特定的格式呢?
    • 我已经完成了这些并且工作正常,但是我需要针对一般情况的解决方案?
    • @Sachin - 通用性如何?这应该允许使用 EF 连接到任何数据库。
    猜你喜欢
    • 2015-11-05
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 2013-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多