好的,所以我们使用MS LocalDB作为数据库来支持我们应用的回归测试。我们有一个非常复杂的模式和发布配置文件,因此我们在C#代码中使用'create db on attach',然后使用SQLCMD运行我们的脚本以使db达到当前版本,插入一些测试数据,运行我们的测试,撕掉所有内容通常这很好。
我最近注意到,如果MDF文件的路径嵌套太深,则SQLCMD失败并显示“Sqlcmd:' - d':参数太长(最多为128个字符)”错误,这是正确的,因为{{ 3}},the -d param to sqlcmd is a database name。
“不用担心”我心想,“我只是把它变成一条相对的道路,一切都会很棒!”亲爱的读者,我有多么错!将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工作目录是Source目录的父目录。 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();
因此,我可以轻松地使用“AttachDbFilename = | DataDirectory | \ TestDb.mdf;”在C#连接字符串中使用相对路径。我也可以通过将项目重新定位到C:\驱动器的根目录并缩短路径来解决这个问题,但这似乎是一个hacky解决方法。
有没有办法在sqlcmd的参数中使用相对路径,这样我就不必使用绝对路径了?我在网上找到的使用sqlcmd和localdb的每个例子都使用绝对路径,唯一的相对路径是C#apps的连接字符串,我们已经使用过了。提前谢谢。