Skip to content
Merged
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
6 changes: 3 additions & 3 deletions samples/database-first-sql-generation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
74 changes: 74 additions & 0 deletions src/JD.Efcpt.Build.Tasks/DetectSqlProject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace JD.Efcpt.Build.Tasks;

/// <summary>
/// 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.
/// </summary>
// Note: Fully qualifying Task to avoid ambiguity with System.Threading.Tasks.Task
public sealed class DetectSqlProject : Microsoft.Build.Utilities.Task
{
/// <summary>
/// Gets or sets the full path to the project file.
/// </summary>
[Required]
public string? ProjectPath { get; set; }

/// <summary>
/// Gets or sets the SqlServerVersion property (for legacy SSDT detection).
/// </summary>
public string? SqlServerVersion { get; set; }

/// <summary>
/// Gets or sets the DSP property (for legacy SSDT detection).
/// </summary>
public string? DSP { get; set; }

/// <summary>
/// Gets a value indicating whether the project is a SQL project.
/// </summary>
[Output]
public bool IsSqlProject { get; private set; }

/// <summary>
/// Executes the task to detect if the project is a SQL database project.
/// </summary>
/// <returns>True if the task executes successfully; otherwise, false.</returns>
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;
}
}
36 changes: 25 additions & 11 deletions src/JD.Efcpt.Build/buildTransitive/JD.Efcpt.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,31 @@
<!-- Derive UseNullableReferenceTypes from project's Nullable setting for zero-config scenarios -->
<EfcptConfigUseNullableReferenceTypes Condition="'$(EfcptConfigUseNullableReferenceTypes)'=='' and ('$(Nullable)'=='enable' or '$(Nullable)'=='Enable')">true</EfcptConfigUseNullableReferenceTypes>
<EfcptConfigUseNullableReferenceTypes Condition="'$(EfcptConfigUseNullableReferenceTypes)'=='' and '$(Nullable)'!=''">false</EfcptConfigUseNullableReferenceTypes>
</PropertyGroup>

<!--
SQL Project Detection: Detect if this is a SQL database project (not an EF Core consumer project).
<!--
SQL Project Detection: Detect if this is a SQL database project (not an EF Core consumer project).

Detection logic:
- Microsoft.Build.Sql SDK: Check for $(SqlServerVersion) or $(DSP) properties
- MSBuild.Sdk.SqlProj: Check for $(SqlServerVersion)
Detection logic (in priority order):
1. Check if project file Sdk attribute references Microsoft.Build.Sql or MSBuild.Sdk.SqlProj
2. Fall back to MSBuild properties ($(SqlServerVersion) or $(DSP)) for legacy SSDT projects

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)'=='' and ('$(SqlServerVersion)' != '' or '$(DSP)' != '')">true</_EfcptIsSqlProject>
<_EfcptIsSqlProject Condition="'$(_EfcptIsSqlProject)'==''">false</_EfcptIsSqlProject>
</PropertyGroup>
This must be in the targets file (not props) because SDK properties like SqlServerVersion
are not available when props files are evaluated.
-->
<Target Name="_EfcptDetectSqlProject" BeforeTargets="BeforeBuild;BeforeRebuild">
<DetectSqlProject
ProjectPath="$(MSBuildProjectFullPath)"
SqlServerVersion="$(SqlServerVersion)"
DSP="$(DSP)">
<Output TaskParameter="IsSqlProject" PropertyName="_EfcptIsSqlProject" />
</DetectSqlProject>

<!-- Defensive: ensure the property is always set, even if the task encounters an unexpected scenario -->
<PropertyGroup>
<_EfcptIsSqlProject Condition="'$(_EfcptIsSqlProject)'==''">false</_EfcptIsSqlProject>
</PropertyGroup>
</Target>

<!--
Determine the correct task assembly path based on MSBuild runtime and version.
Expand Down Expand Up @@ -117,6 +128,9 @@
<UsingTask TaskName="JD.Efcpt.Build.Tasks.AddSqlFileWarnings"
AssemblyFile="$(_EfcptTaskAssembly)" />

<UsingTask TaskName="JD.Efcpt.Build.Tasks.DetectSqlProject"
AssemblyFile="$(_EfcptTaskAssembly)" />

<!--
SDK Version Check: Warns users when a newer SDK version is available.
Opt-in via EfcptCheckForUpdates=true. Results are cached for 24 hours.
Expand Down
Loading