diff --git a/samples/database-first-sql-generation/README.md b/samples/database-first-sql-generation/README.md index eda279d..78c9b0d 100644 --- a/samples/database-first-sql-generation/README.md +++ b/samples/database-first-sql-generation/README.md @@ -81,10 +81,10 @@ database-first-sql-generation/ ### Automatic Detection -JD.Efcpt.Build uses MSBuild properties to detect SQL projects: +JD.Efcpt.Build detects SQL projects by checking the project file's SDK attribute: -- **Microsoft.Build.Sql**: Checks for `$(DSP)` property -- **MSBuild.Sdk.SqlProj**: Checks for `$(SqlServerVersion)` property +- **SDK-based projects**: Checks if the `Sdk` attribute contains `Microsoft.Build.Sql` or `MSBuild.Sdk.SqlProj` +- **Legacy SSDT projects**: Falls back to checking MSBuild properties (`$(DSP)` or `$(SqlServerVersion)`) When detected, it runs SQL generation instead of EF Core generation. diff --git a/src/JD.Efcpt.Build.Tasks/DetectSqlProject.cs b/src/JD.Efcpt.Build.Tasks/DetectSqlProject.cs new file mode 100644 index 0000000..b8fb150 --- /dev/null +++ b/src/JD.Efcpt.Build.Tasks/DetectSqlProject.cs @@ -0,0 +1,74 @@ +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +namespace JD.Efcpt.Build.Tasks; + +/// +/// MSBuild task that detects whether the current project is a SQL database project. +/// Uses the SqlProjectDetector to check for SDK-based projects first, then falls back to property-based detection. +/// +// Note: Fully qualifying Task to avoid ambiguity with System.Threading.Tasks.Task +public sealed class DetectSqlProject : Microsoft.Build.Utilities.Task +{ + /// + /// Gets or sets the full path to the project file. + /// + [Required] + public string? ProjectPath { get; set; } + + /// + /// Gets or sets the SqlServerVersion property (for legacy SSDT detection). + /// + public string? SqlServerVersion { get; set; } + + /// + /// Gets or sets the DSP property (for legacy SSDT detection). + /// + public string? DSP { get; set; } + + /// + /// Gets a value indicating whether the project is a SQL project. + /// + [Output] + public bool IsSqlProject { get; private set; } + + /// + /// Executes the task to detect if the project is a SQL database project. + /// + /// True if the task executes successfully; otherwise, false. + public override bool Execute() + { + if (string.IsNullOrWhiteSpace(ProjectPath)) + { + Log.LogError("ProjectPath is required."); + return false; + } + + // First, check if project uses a modern SQL SDK via SDK attribute + var usesModernSdk = SqlProjectDetector.IsSqlProjectReference(ProjectPath); + + if (usesModernSdk) + { + IsSqlProject = true; + Log.LogMessage(MessageImportance.Low, + "Detected SQL project via SDK attribute: {0}", ProjectPath); + return true; + } + + // Fall back to property-based detection for legacy SSDT projects + var hasLegacyProperties = !string.IsNullOrEmpty(SqlServerVersion) || !string.IsNullOrEmpty(DSP); + + if (hasLegacyProperties) + { + IsSqlProject = true; + Log.LogMessage(MessageImportance.Low, + "Detected SQL project via MSBuild properties (legacy SSDT): {0}", ProjectPath); + return true; + } + + IsSqlProject = false; + Log.LogMessage(MessageImportance.Low, + "Not a SQL project: {0}", ProjectPath); + return true; + } +} diff --git a/src/JD.Efcpt.Build/buildTransitive/JD.Efcpt.Build.targets b/src/JD.Efcpt.Build/buildTransitive/JD.Efcpt.Build.targets index 5c1d5c5..820d12b 100644 --- a/src/JD.Efcpt.Build/buildTransitive/JD.Efcpt.Build.targets +++ b/src/JD.Efcpt.Build/buildTransitive/JD.Efcpt.Build.targets @@ -10,20 +10,31 @@ true false + - - <_EfcptIsSqlProject Condition="'$(_EfcptIsSqlProject)'=='' and ('$(SqlServerVersion)' != '' or '$(DSP)' != '')">true - <_EfcptIsSqlProject Condition="'$(_EfcptIsSqlProject)'==''">false - + This must be in the targets file (not props) because SDK properties like SqlServerVersion + are not available when props files are evaluated. + --> + + + + + + + + <_EfcptIsSqlProject Condition="'$(_EfcptIsSqlProject)'==''">false + +