dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.78k stars 3.19k forks source link

Show a warning when the tools are used with a platform-specific app #32835

Open Iztharoth opened 10 months ago

Iztharoth commented 10 months ago

Hi Folks,

I am building a WinUI 3 app and want to use SQLite using ef core. When using the Microsoft.Extensions.Hosting package, the dotnet ef migrations add command doesn't give any errors but also doesn't give or log any errors. When removed from the .csproj file the and use Microsoft.Extensions.DependencyInjection, the migration is created without any problems.

I created a small sample 3 app with ef core. In the current state of the project within App1.zip is Microsoft.Extensions.Hosting included.

Am I missing something?

How to reproduce?

  1. Open project, :)
  2. Run dotnet ef migrations add InitialCreate -v
  3. Watch it do nothing
  4. Remove Microsoft.Extensions.Hosting in the .csproj
  5. Run dotnet clean
  6. Run dotnet ef migrations add InitialCreate -v again
  7. Watch it create a migration

Code

Project zip

App1.zip

The constructor in the App.xaml.cs.

    public App()
    {
        this.InitializeComponent();

        var serviceProvider = new ServiceCollection().AddDbContext<AppDbContext>(ServiceLifetime.Transient).BuildServiceProvider();

        //var host = new HostBuilder()
        //    .ConfigureServices(services =>
        //    services.AddDbContext<AppDbContext>(ServiceLifetime.Transient))
        //    .Build();
        //host.Start();
    }

Context factory

internal class TestDatabaseContextFactory : IDesignTimeDbContextFactory<AppDbContext>
{
    public AppDbContext CreateDbContext(string[] args)
    {
        var folder = Environment.SpecialFolder.LocalApplicationData;
        var path = Environment.GetFolderPath(folder);
        var DbPath = System.IO.Path.Join(path, "blogging.db");
        var optionsBuilder = new DbContextOptionsBuilder<AppDbContext>();
        optionsBuilder.UseSqlite($"Data Source={DbPath}");

        return new AppDbContext(optionsBuilder.Options);
    }
}

Output

Using Microsoft.Extensions.DependencyInjection

PS C:\Users\User\source\repos\App1\App1> dotnet ef migrations add InitialCreate -v
Using project 'C:\Users\User\source\repos\App1\App1\App1.csproj'.
Using startup project 'C:\Users\User\source\repos\App1\App1\App1.csproj'.
Writing 'C:\Users\User\source\repos\App1\App1\obj\App1.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\User\AppData\Local\Temp\tmpp110d3.tmp /verbosity:quiet /nologo C:\Users\User\source\repos\App1\App1\App1.csproj
Writing 'C:\Users\User\source\repos\App1\App1\obj\App1.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\User\AppData\Local\Temp\tmp5psv0t.tmp /verbosity:quiet /nologo C:\Users\User\source\repos\App1\App1\App1.csproj
Build started...
dotnet build C:\Users\User\source\repos\App1\App1\App1.csproj /verbosity:quiet /nologo /p:PublishAot=false
c:\program files\dotnet\sdk\8.0.101\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): warning NETSDK1206: Found version-specific or distribution-specific runtime identifier(s): win10-arm64, win10-x64, win10-x86. Affected libraries: Microsoft.WindowsAppSDK. In .NET 8.0 and higher, assets for version-specific and distribution-specific runtime identifiers will not be found by default. See https://aka.ms/dotnet/rid-usage for details. [C:\Users\User\source\repos\App1\App1\App1.csproj]

Build succeeded.

c:\program files\dotnet\sdk\8.0.101\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): warning NETSDK1206: Found version-specific or distribution-specific runtime identifier(s): win10-arm64, win10-x64, win10-x86. Affected libraries: Microsoft.WindowsAppSDK. In .NET 8.0 and higher, assets for version-specific and distribution-specific runtime identifiers will not be found by default. See https://aka.ms/dotnet/rid-usage for details. [C:\Users\User\source\repos\App1\App1\App1.csproj]
    1 Warning(s)
    0 Error(s)

Time Elapsed 00:00:14.96
Build succeeded.
dotnet exec --depsfile C:\Users\User\source\repos\App1\App1\bin\Debug\net8.0-windows10.0.19041.0\App1.deps.json --additionalprobingpath C:\Users\User\.nuget\packages --additionalprobingpath "C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages" --additionalprobingpath "c:\program files\dotnet\sdk\NuGetFallbackFolder" --runtimeconfig C:\Users\User\source\repos\App1\App1\bin\Debug\net8.0-windows10.0.19041.0\App1.runtimeconfig.json C:\Users\User\.dotnet\tools\.store\dotnet-ef\8.0.1\dotnet-ef\8.0.1\tools\net8.0\any\tools\netcoreapp2.0\any\ef.dll migrations add InitialCreate --assembly C:\Users\User\source\repos\App1\App1\bin\Debug\net8.0-windows10.0.19041.0\App1.dll --project C:\Users\User\source\repos\App1\App1\App1.csproj --startup-assembly C:\Users\User\source\repos\App1\App1\bin\Debug\net8.0-windows10.0.19041.0\App1.dll --startup-project C:\Users\User\source\repos\App1\App1\App1.csproj --project-dir C:\Users\User\source\repos\App1\App1\ --root-namespace App1 --language C# --framework net8.0-windows10.0.19041.0 --working-dir C:\Users\User\source\repos\App1\App1 --verbose
Using assembly 'App1'.
Using startup assembly 'App1'.
Using application base 'C:\Users\User\source\repos\App1\App1\bin\Debug\net8.0-windows10.0.19041.0'.
Using working directory 'C:\Users\User\source\repos\App1\App1'.
Using root namespace 'App1'.
Using project directory 'C:\Users\User\source\repos\App1\App1\'.
Remaining arguments: .
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Found IDesignTimeDbContextFactory implementation 'TestDatabaseContextFactory'.
Found DbContext 'AppDbContext'.
Finding application service provider in assembly 'App1'...
Finding Microsoft.Extensions.Hosting service provider...
No static method 'CreateHostBuilder(string[])' was found on class 'Program'.
No application service provider was found.
Finding DbContext classes in the project...
Using DbContext factory 'TestDatabaseContextFactory'.
Using context 'AppDbContext'.
Finding design-time services referenced by assembly 'App1'...
Finding design-time services referenced by assembly 'App1'...
No referenced design-time services were found.
Finding design-time services for provider 'Microsoft.EntityFrameworkCore.Sqlite'...
Using design-time services from provider 'Microsoft.EntityFrameworkCore.Sqlite'.
Finding IDesignTimeServices implementations in assembly 'App1'...
No design-time services were found.
Writing migration to 'C:\Users\User\source\repos\App1\App1\Migrations\20240115212727_InitialCreate.cs'.
Writing model snapshot to 'C:\Users\User\source\repos\App1\App1\Migrations\AppDbContextModelSnapshot.cs'.
'AppDbContext' disposed.
Done. To undo this action, use 'ef migrations remove'
PS C:\Users\User\source\repos\App1\App1>

Using Microsoft.Extensions.Hosting

PS C:\Users\User\source\repos\App1\App1> dotnet ef migrations add InitialCreate -v
Using project 'C:\Users\User\source\repos\App1\App1\App1.csproj'.
Using startup project 'C:\Users\User\source\repos\App1\App1\App1.csproj'.
Writing 'C:\Users\User\source\repos\App1\App1\obj\App1.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\User\AppData\Local\Temp\tmp3zndbe.tmp /verbosity:quiet /nologo C:\Users\User\source\repos\App1\App1\App1.csproj
Writing 'C:\Users\User\source\repos\App1\App1\obj\App1.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\User\AppData\Local\Temp\tmpz5aegy.tmp /verbosity:quiet /nologo C:\Users\User\source\repos\App1\App1\App1.csproj
Build started...
dotnet build C:\Users\User\source\repos\App1\App1\App1.csproj /verbosity:quiet /nologo /p:PublishAot=false
c:\program files\dotnet\sdk\8.0.101\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): warning NETSDK1206: Found version-specific or distribution-specific runtime identifier(s): win10-arm64, win10-x64, win10-x86. Affected libraries: Microsoft.WindowsAppSDK. In .NET 8.0 and higher, assets for version-specific and distribution-specific runtime identifiers will not be found by default. See https://aka.ms/dotnet/rid-usage for details. [C:\Users\User\source\repos\App1\App1\App1.csproj]

Build succeeded.

c:\program files\dotnet\sdk\8.0.101\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(284,5): warning NETSDK1206: Found version-specific or distribution-specific runtime identifier(s): win10-arm64, win10-x64, win10-x86. Affected libraries: Microsoft.WindowsAppSDK. In .NET 8.0 and higher, assets for version-specific and distribution-specific runtime identifiers will not be found by default. See https://aka.ms/dotnet/rid-usage for details. [C:\Users\User\source\repos\App1\App1\App1.csproj]
    1 Warning(s)
    0 Error(s)

Time Elapsed 00:00:08.86
Build succeeded.
dotnet exec --depsfile C:\Users\User\source\repos\App1\App1\bin\Debug\net8.0-windows10.0.19041.0\App1.deps.json --additionalprobingpath C:\Users\User\.nuget\packages --additionalprobingpath "C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages" --additionalprobingpath "c:\program files\dotnet\sdk\NuGetFallbackFolder" --runtimeconfig C:\Users\User\source\repos\App1\App1\bin\Debug\net8.0-windows10.0.19041.0\App1.runtimeconfig.json C:\Users\User\.dotnet\tools\.store\dotnet-ef\8.0.1\dotnet-ef\8.0.1\tools\net8.0\any\tools\netcoreapp2.0\any\ef.dll migrations add InitialCreate --assembly C:\Users\User\source\repos\App1\App1\bin\Debug\net8.0-windows10.0.19041.0\App1.dll --project C:\Users\User\source\repos\App1\App1\App1.csproj --startup-assembly C:\Users\User\source\repos\App1\App1\bin\Debug\net8.0-windows10.0.19041.0\App1.dll --startup-project C:\Users\User\source\repos\App1\App1\App1.csproj --project-dir C:\Users\User\source\repos\App1\App1\ --root-namespace App1 --language C# --framework net8.0-windows10.0.19041.0 --working-dir C:\Users\User\source\repos\App1\App1 --verbose
Using assembly 'App1'.
Using startup assembly 'App1'.
Using application base 'C:\Users\User\source\repos\App1\App1\bin\Debug\net8.0-windows10.0.19041.0'.
Using working directory 'C:\Users\User\source\repos\App1\App1'.
Using root namespace 'App1'.
Using project directory 'C:\Users\User\source\repos\App1\App1\'.
Remaining arguments: .
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Found IDesignTimeDbContextFactory implementation 'TestDatabaseContextFactory'.
Found DbContext 'AppDbContext'.
Finding application service provider in assembly 'App1'...
Finding Microsoft.Extensions.Hosting service provider...
Using environment 'Development'.
Using application service provider from Microsoft.Extensions.Hosting.
PS C:\Users\User\source\repos\App1\App1>

Include provider and version information

EF Core version: Database provider: Microsoft.EntityFrameworkCore.SQLite (e.g. Microsoft.EntityFrameworkCore.SqlServer) Target framework: .NET 8 Operating system: Windows 11 IDE: Visual Studio 2022 17.9 Preview

Iztharoth commented 10 months ago

Seems like the same issue as https://github.com/dotnet/efcore/issues/28022

Iztharoth commented 10 months ago

Whoops wrong button šŸ„²

ajcvickers commented 9 months ago

Note for triage: I am able to reproduce this. Also fails for EF7 on .NET 8 and EF7 on .NET 7, so not a regression.

jyrijh commented 8 months ago

I did run into this same issue, and what I did was to comment out this and migrations succeeded

//public ArchiveContext(DbContextOptions<ArchiveContext> options)
//: base(options) { }
Unable to create a 'DbContext' of type ''. The exception 'Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContextOptions`1[ArchiveDb.ArchiveContext]' while attempting to activate 'ArchiveDb.ArchiveContext'.' was thrown while attempting to create an instance. For the different patterns supported at design time
jyrijh commented 8 months ago

And if you add a parameterless constructor to you dbcontext then migrations work also

public ArchiveContext(DbContextOptions<ArchiveContext> options) : base(options) { }

public ArchiveContext() { }
snlyazilim commented 7 months ago

I have the same problem, I added a parameterless constructor and it still didn't work.

Project --> Blazor Web App

mheidari988 commented 7 months ago

I have the same problem when using Microsoft.Extensions.DependencyInjection

iltan987 commented 7 months ago

I also have the same problem. Please fix.

fectus commented 7 months ago

I have the same problem in my Win UI 3 application which I generated by using the Template Studio plugin in VS 2022. My application requires the EF Core 7.0.17 with SQLite and the whole solution targets the net7.0-windows10.0.19041.0. I had to quite outsmart the process by removing the hosting NuGet package Microsoft.Extensions.Hosting as proposed above and commenting out quite a large portion of the Win UI 3 app code that depended on it to get a migration created. It also required me to override the OnConfiguring method in my DB context to specify that the database provider is SQLite with the provided connection string name. Overall, it was not an easy and pleasant process and I hope I will not be required to repeat that anytime soon.

klaasdemunckcgk commented 7 months ago

I'm also facing the same problem. Using a parameterless constructor does not fix the problem.

habtard commented 7 months ago

Issue still exists

Onyshko commented 6 months ago

I had same problem. I had an ASP.Net React project and I had tried to create migration but it didn't work. I had had 2 startup project one for React one and for API and I had tried choosing only API project and it's worked.

ayodejii commented 6 months ago

I currently am having this problem while trying to run db migration via github actions.

fsalamah commented 5 months ago

And if you add a parameterless constructor to you dbcontext then migrations work also

public ArchiveContext(DbContextOptions<ArchiveContext> options) : base(options) { }

public ArchiveContext() { }

Adding the empty constructor resolved the issue for me too. Thank you. I spent a whole day on this one :|

AndriySvyryd commented 2 months ago

https://github.com/dotnet/efcore/pull/34082 should improve some cases starting with 9.0.0-rc1 when IDesignTimeDbContextFactory is implemented. But in general, EF tooling doesn't support platform-specific apps and we recommend using Migrations projects

Haukinger commented 3 weeks ago

The first sentence of the linked page is funny in this context: You may want to store your migrations in a different project than the one containing your DbContext - should read something like You cannot store your migrations in a platform-specific project..