【问题标题】:Set connection string for database access for production build Winforms app为生产构建 Winforms 应用程序设置数据库访问的连接字符串
【发布时间】:2022-01-16 02:16:01
【问题描述】:

我正在做一个 Winforms 项目,我只是设置安装程序的安装文件。

场景

我设置的连接字符串是这样的:

 SqlConnection con = new SqlConnection(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=F:\Application\MyAppv1.0\MyApp\DB.mdf;Integrated Security=True");
 return con;

在这里,我使用个人位置的本地数据库。

问题

在客户端的 PC 上安装时,还附加了数据库,因此安装的文件将在 C:\Program Files\Author\MyAppv1.0 上。当我使用相同的连接字符串时,应用程序显示异常。那么,我应该在设置创建期间更新该位置的连接字符串吗? (我正在使用 MSI)。

对于这种情况,有什么常用的方法吗?

我的目标是让已安装的应用程序使用数据库,该数据库也位于同一安装位置,名为 DB.mdf,并随设置提供。

提前谢谢大家。

【问题讨论】:

  • 您应该正确附加数据库,然后在连接字符串中设置实际的数据库名称。请参阅what's the issue with AttachDbFilename 即使 LocalDB 也允许正确附加数据库,请使用 CREATE DATABASE ... FOR ATTACH
  • 将连接字符串放入配置文件中。使用配置转换来更改非本地构建/部署中的设置。
  • 这就是我设置连接设置的方式<connectionStrings> <add name="DBConnectionString" connectionString="Data Source=DB.mdf;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings> 安装后仍然无法正常工作.. 无法访问数据库是例外。 @Charlieface,@Flydog57
  • 附加数据库时,您给数据库提供了什么实际名称(不是文件名)? DB.mdf 是附加数据库的奇怪名称,您需要引用它 CREATE DATABASE [DB.mdf]...
  • 其实就是MyAppDB是数据库的名字。我们是否必须使用 CREATE Query 再次创建数据库?我已经全部设置好了数据库。 @查理脸

标签: c# winforms connection-string release


【解决方案1】:

Do not use AttachDbFilename, it has many issues. 相反,通常使用CREATE DATABASE...FOR ATTACH 附加您的数据库。

在您的应用启动时,您可以使用master 作为当前数据库连接到服务器,并检查您的数据库是否存在。如果它不存在,您可以创建它。

private static void CheckDbExistence(string connectionString)
{
    const string query = @"
IF NOT EXISTS (SELECT 1
    FROM sys.databases
    WHERE name = 'MyDb')
BEGIN

    DECLARE @sql nvarchar(max) = N'
CREATE DATABASE MyDb ON
  (FILENAME = ' + QUOTENAME(@mdf, '''') + '),   
  (FILENAME = ' + QUOTENAME(@ldf, '''') + ')
  FOR ATTACH;
';

    EXEC (@sql);
END;
    ";
    var csb = new SqlConnectionStringBuilder(connectionString);
    csb.Initial Catalog = "master";
    using (var conn = new SqlConnection(csb.ConnectionString))
    using (var comm = new SqlCommand(query, conn))
    {
        comm.Parameters.Add("@mdf", SqlDbType.NVarChar, 255).Value = Path.Combine(Environment.CurrentDirectory, "MyDb.mdf");
        comm.Parameters.Add("@ldf", SqlDbType.NVarChar, 255).Value = Path.Combine(Environment.CurrentDirectory, "MyDb.ldf");
        conn.Open();
        comm.ExecuteNonQuery();
    }
}

【讨论】:

  • 那我想在 LocalDB 上创建的表和存储过程呢?
  • 这将存储在.mdf 文件和.ldf 日志文件中,您只是附加一个现有数据库
  • 我在“FOR”附近的语法不正确。以及我应该在初始阶段提到什么连接字符串?这是正确的吗 => Server=localhost;Integrated security=SSPI;database=master
  • 对不起,语法有点不对劲,看起来CREATE DATABASE不能参数化,所以需要使用动态SQL。 csb.Initial Catalog = "master"; 的业务是让您可以保持连接字符串相同,但只需在连接前更改数据库即可。所以你可以使用database=MyDB,这段代码会切换到master进行连接
  • 动态 SQL 像这样 => str = "CREATE DATABASE MyDB ON PRIMARY " + "(NAME = MyDB_Data, " + "FILENAME = 'C:\\MyDB.mdf', " + "SIZE = 2MB, MAXSIZE = 10MB, FILEGROWTH = 10%)" + "LOG ON (NAME = MyDB_Log, " + "FILENAME = 'C:\\MyDB.ldf', " + "SIZE = 1MB, " + "MAXSIZE = 5MB, " + "FILEGROWTH = 10%)"; SqlCommand myCommand = new SqlCommand(str, myConn); myConn.Open(); myCommand.ExecuteNonQuery();
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 2016-09-29
  • 1970-01-01
相关资源
最近更新 更多