diff --git a/src/dotnet-ef/Properties/Resources.Designer.cs b/src/dotnet-ef/Properties/Resources.Designer.cs index c722ed44878..75b9b5c17cd 100644 --- a/src/dotnet-ef/Properties/Resources.Designer.cs +++ b/src/dotnet-ef/Properties/Resources.Designer.cs @@ -459,6 +459,14 @@ public static string PrecompileQueriesDescription public static string PrecompileQueriesWarning => GetString("PrecompileQueriesWarning"); + /// + /// Startup project '{startupProject}' targets a platform-specific framework: '{targetFrameworkValue}'. The Entity Framework Core .NET Command-line Tools might not function correctly. Implement IDesignTimeDbContextFactory<> to ensure design-time tools work correctly with this project. See https://aka.ms/efcore-docs-migrations-projects for more information. + /// + public static string PlatformSpecificProject(object? startupProject, object? targetFrameworkValue) + => string.Format( + GetString("PlatformSpecificProject", nameof(startupProject), nameof(targetFrameworkValue)), + startupProject, targetFrameworkValue); + /// /// Prefix output with level. /// diff --git a/src/dotnet-ef/Properties/Resources.resx b/src/dotnet-ef/Properties/Resources.resx index 323919ca847..5788b6d0def 100644 --- a/src/dotnet-ef/Properties/Resources.resx +++ b/src/dotnet-ef/Properties/Resources.resx @@ -330,6 +330,9 @@ Query precompilation is an experimental feature and should be used with caution. + + Startup project '{startupProject}' targets a platform-specific framework: '{targetFrameworkValue}'. The Entity Framework Core .NET Command-line Tools might not function correctly. Implement IDesignTimeDbContextFactory<> to ensure design-time tools work correctly with this project. See https://aka.ms/efcore-docs-migrations-projects for more information. + Prefix output with level. diff --git a/src/dotnet-ef/RootCommand.cs b/src/dotnet-ef/RootCommand.cs index fa70430b979..192fa7d3846 100644 --- a/src/dotnet-ef/RootCommand.cs +++ b/src/dotnet-ef/RootCommand.cs @@ -106,6 +106,13 @@ protected override int Execute(string[] _) startupProject.AssemblyName + ".runtimeconfig.json"); var projectAssetsFile = startupProject.ProjectAssetsFile; + if (!string.IsNullOrEmpty(startupProject.TargetPlatformIdentifier) + || HasPlatformInTargetFramework(startupProject.TargetFramework)) + { + Reporter.WriteWarning( + Resources.PlatformSpecificProject(startupProject.ProjectName, startupProject.TargetFramework)); + } + var targetFramework = new FrameworkName(startupProject.TargetFrameworkMoniker!); if (targetFramework.Identifier == ".NETFramework") { @@ -313,6 +320,18 @@ private static string GetVersion() => typeof(RootCommand).Assembly.GetCustomAttribute()! .InformationalVersion; + private static bool HasPlatformInTargetFramework(string? targetFramework) + { + if (string.IsNullOrEmpty(targetFramework)) + { + return false; + } + + // Check for netX.Y-Z form (e.g. net8.0-windows10.0.19041.0) + var dashIndex = targetFramework.IndexOf('-'); + return dashIndex > 0 && dashIndex < targetFramework.Length - 1; + } + private static bool ShouldHelp(IReadOnlyList commands, IList args) => args.Count == 0 || commands.Count == 0