2

好的,所以我们使用MS LocalDB作为数据库来支持我们应用程序的回归测试。我们有一个相当复杂的架构和发布配置文件,所以我们在 C# 代码中使用“create db on attach”,然后使用 SQLCMD 运行我们的脚本以将数据库升级到当前版本,插入一些测试数据,运行我们的测试,撕掉所有东西下等。通常这工作正常。

我最近注意到,如果 MDF 文件的路径嵌套太深,那么 SQLCMD 会失败并出现“Sqlcmd: '-d': Argument too long (maximum is 128 characters)”错误,这是正确的,因为 -d 参数sqlcmd 是一个数据库名称,它只能是 128 个字符长

“不用担心”我心想,“我只要让它成为一条相对路径,一切都会很棒!”。哦,亲爱的读者,我错了!将 dbname 更改为相对于 sqlcmd 工作目录的路径只会导致 sqlcmd 登录错误:

Sqlcmd: Error: Microsoft SQL Server Native Client 11.0 : Login failed for user 'DOMAIN\myUser'..
Sqlcmd: Error: Microsoft SQL Server Native Client 11.0 : Cannot open database "Source\Solution.Name\Solution.Name.Tests.Regression\bin\DEVT\TestDb.mdf" requested by the login. The login failed..

sqlcmd 使用的命令等价于以下命令:

"C:\Program Files\Microsoft SQL Server\110\Tools\Binn\SQLCMD.EXE" -S (localdb)\v11.0 -i "path\to\baseline.sql" -E -e -b -r1 -d "Source\Solution.Name\Solution.Name.Tests.Regression\bin\DEVT\TestDb.mdf"

其中 sqlcmd 工作目录是源目录的父目录。Sqlcmd 是从我们的 C# 代码中运行的,如下所示:

        var process = new Process
        {
            StartInfo = { FileName = "C:\\Program Files\\Microsoft SQL Server\\110\\Tools\\Binn\\SQLCMD.EXE" }
        };

        process.StartInfo.Arguments = " -S (localdb)\v11.0 -i \"path\\to\\baseline.sql\" -E -e -b -r1 -d \"Source\\Solution.Name\\Solution.Name.Tests.Regression\\bin\\DEVT\\TestDb.mdf\"";
        process.StartInfo.WorkingDirectory = "C:\users\myUser\projects\projectName\";
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.CreateNoWindow = true;
        process.StartInfo.RedirectStandardError = true;

        try
        {
            process.Start();
            string error = process.StandardError.ReadToEnd();
            process.WaitForExit();
        }
        catch(Exception e)
        {
            //error handling, print error string etc
        }

因此,在我们的回归测试中,localDB 已附加在前面:

            SqlConnection conn = new SqlConnection("Data Source=(LocalDB)\\v11.0;AttachDbFilename=|DataDirectory|\\TestDb.mdf;Integrated Security=True;MultipleActiveResultSets=True;Connect Timeout=30");
            conn.Open();

因此,我可以轻松地在 C# 连接字符串中使用“AttachDbFilename=|DataDirectory|\TestDb.mdf;”的相对路径。我也可以通过将项目重新定位到 C:\ 驱动器的根目录并缩短路径来解决此问题,但这似乎是一个 hacky 解决方法。

有没有办法在 sqlcmd 的参数中使用相对路径,这样我就不必使用绝对路径?我在网上找到的将 sqlcmd 与 localdb 结合使用的每个示例都使用绝对路径,唯一的相对路径位于我们已经使用的 C# 应用程序的连接字符串中。提前致谢。

4

0 回答 0