Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/Microsoft.Build.Sql/sdk/Sdk.targets
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,22 @@
<Build Remove="@(BuildExtensionConfiguration)" />
<Build Remove="@(DeploymentExtensionConfiguration)" />
</ItemGroup>

<!-- Enhance SqlReferencePath items with ProjectReference metadata to preserve database references in transitive dependencies (Fix for issue #608) -->
<Target Name="PreserveProjectReferenceDatabaseMetadata" AfterTargets="ResolveArtifactReferences">
<ItemGroup>
<!-- Update SqlReferencePath items with the database metadata -->
<SqlReferencePath Condition="'%(ProjectReferenceWithConfiguration.DatabaseSqlCmdVariable)' != ''">
<DatabaseSqlCmdVariable>%(ProjectReferenceWithConfiguration.DatabaseSqlCmdVariable)</DatabaseSqlCmdVariable>
</SqlReferencePath>
<SqlReferencePath Condition="'%(ProjectReferenceWithConfiguration.ServerSqlCmdVariable)' != ''">
<ServerSqlCmdVariable>%(ProjectReferenceWithConfiguration.ServerSqlCmdVariable)</ServerSqlCmdVariable>
</SqlReferencePath>
<SqlReferencePath Condition="'%(ProjectReferenceWithConfiguration.DatabaseVariableLiteralValue)' != ''">
<DatabaseVariableLiteralValue>%(ProjectReferenceWithConfiguration.DatabaseVariableLiteralValue)</DatabaseVariableLiteralValue>
</SqlReferencePath>
</ItemGroup>
</Target>

<!-- Target to resolve package references into database references to the underlying DACPACs inside the packages -->
<Target Name="ResolveDacpacPackageReferences" BeforeTargets="ResolveArtifactReferences">
Expand Down
51 changes: 51 additions & 0 deletions test/Microsoft.Build.Sql.Tests/BuildTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -505,5 +505,56 @@ public void VerifyBuildTargetPath()
Assert.AreEqual(string.Empty, stdError);
StringAssert.Contains($"Target path from PrintTargetPath: {GetDacpacPath()}", stdOutput, "Target path not found in output.");
}

[Test]
// https://github.com/microsoft/DacFx/issues/608
[Description("Verifies build with transitive project references with DatabaseSqlCmdVariable should not have name collisions.")]
public void VerifyBuildWithTransitiveProjectReferencesWithDatabaseVariables()
{
// Create 3 sqlproj projects like Sql1, Sql2, Sql3
string projectSql1Dir = Path.Combine(WorkingDirectory, "Sql1");
string projectSql2Dir = Path.Combine(WorkingDirectory, "Sql2");
string projectSql3Dir = Path.Combine(WorkingDirectory, "Sql3");
string projectSql1 = Path.Combine(projectSql1Dir, "Sql1.sqlproj");
string projectSql2 = Path.Combine(projectSql2Dir, "Sql2.sqlproj");
string projectSql3 = Path.Combine(projectSql3Dir, "Sql3.sqlproj");

// Create identical Table1.sql in all three projects
string table1Sql = "CREATE TABLE Table1 (Id INT);\nGO\n";
Directory.CreateDirectory(projectSql1Dir);
Directory.CreateDirectory(projectSql2Dir);
Directory.CreateDirectory(projectSql3Dir);

File.WriteAllText(Path.Combine(projectSql1Dir, "Table1.sql"), table1Sql);
File.WriteAllText(Path.Combine(projectSql2Dir, "Table1.sql"), table1Sql);
File.WriteAllText(Path.Combine(projectSql3Dir, "Table1.sql"), table1Sql);

// Copy from template to create project files
File.Copy(
Path.Combine(TestContext.CurrentContext.TestDirectory, "Template", "project.sqlproj"),
projectSql1);
File.Copy(
Path.Combine(TestContext.CurrentContext.TestDirectory, "Template", "project.sqlproj"),
projectSql2);
File.Copy(
Path.Combine(TestContext.CurrentContext.TestDirectory, "Template", "project.sqlproj"),
projectSql3);

// Add references with DatabaseSqlCmdVariable
// Sql2 references Sql1 with DatabaseSqlCmdVariable="Sql1"
ProjectUtils.AddItemGroup(projectSql2, "ProjectReference", new string[] { projectSql1 },
item => item.AddMetadata("DatabaseSqlCmdVariable", "Sql1"));

// Sql3 references Sql2 with DatabaseSqlCmdVariable="Sql2"
ProjectUtils.AddItemGroup(projectSql3, "ProjectReference", new string[] { projectSql2 },
item => item.AddMetadata("DatabaseSqlCmdVariable", "Sql2"));

// Build Sql3 project
int exitCode = this.RunGenericDotnetCommand($"build {projectSql3}", out string stdOutput, out string stdError);

// Build should succeed - different databases should not have name collisions
Assert.AreEqual(0, exitCode, "Build failed with error " + stdError);
Assert.AreEqual(string.Empty, stdError);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<!-- Multi-targeting to test SDK on different .NET versions, requires all of the following SDKs to be installed. -->
<!-- To build and test only one version, add -f to dotnet command. -->
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<!-- Disable EOL target framework check since we're explicitly testing against older .NET versions. -->
<CheckEolTargetFramework>false</CheckEolTargetFramework>
Expand Down