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.72k stars 3.17k forks source link

Throw better exception when app might be using old ASP.NET pattern #8888

Closed shawnwildermuth closed 7 years ago

shawnwildermuth commented 7 years ago

Describe what is not working as expected.

I expected that the startup registration would allow me to use the EF Tools without implementing a IDbConnectionFactory. I do not have an empty constructor on my context class, but by isn't the tooling using DI to create an instance? Here is my DbContext class:

  public class VacationContext : DbContext
  {
    private IConfiguration _config;

    public VacationContext(IConfiguration config, DbContextOptions builder): base(builder)
    {
      _config = config;
    }

    public DbSet<VacationRequest> VacationRequests { get; set; }
    public DbSet<Employee> Employees { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
      base.OnConfiguring(optionsBuilder);

      optionsBuilder.UseSqlServer(_config["Data:MainConnection"]);
    }
  }

If you are seeing an exception, include the full exceptions details (message and stack trace).

d:\courses\PS\aspnetcore2\Examples\Exemplar\VacationPicker>dotnet ef database drop

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:05.15
No parameterless constructor was found on 'VacationContext'. Either add a parameterless constructor to 'VacationContext' or add an implementation of 'IDbContextFactory<VacationContext>' in the same assembly as 'VacationContext'.

Steps to reproduce

Include a complete code listing (or project/solution) that we can run to reproduce the issue.

Partial code listings, or multiple fragments of code, will slow down our response or cause us to push the issue back to you to provide code to reproduce the issue.

<code listing>

Further technical details

EF Core version: (found in .csproj file)

 <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0-preview1-final" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.0-preview1-final" />
    <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0-preview1-final" />

Database Provider: Microsoft.EntityFrameworkCore.SqlServer Operating system: Win10 IDE: VS2017 Preview 1

bricelam commented 7 years ago

Dupe of #8164. This will be fixed in 2.0.0-preview2-final.

ajcvickers commented 7 years ago

ASP.NET Core changed the default pattern for applications in 2.0. Instead of having a ConfigureServices call, there is now a Main method with a BuildWebHost method split out. It was explicitly stated by @DamianEdwards that EF does not need to try to keep supporting the old pattern and instead old applications should:

However, our exception message only suggests the latter, which means that people will not be aware that updating their app to the new pattern is a solution. We should update the message with a fwlink (@divega) to documentation on how to update 1.x ASP.NET Core app to the 2.0 pattern.

divega commented 7 years ago

I have created https://go.microsoft.com/fwlink/?linkid=851728. Currently it points to one of the ASP.NET Core walkthroughs, but we should update it as part of https://github.com/aspnet/EntityFramework.Docs/issues/409.

shawnwildermuth commented 7 years ago

I don't quite get this, does this mean that for separate data projects, we no longer need a startup class to support EF Tooling? Instead we should do what in Main to support it without needing to implement the IDbContextFactory? I'm seeing this is a new 2.0 project, not a converted 1.x project.

This is the program.cs:

namespace VacationPicker
{
  public class Program
  {
    public static void Main(string[] args)
    {
      BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();
  }
}
divega commented 7 years ago

@shawnwildermuth AFAIR, in 2.0-preview1 we were in an intermediary state in which we didn't support the Program.BuildWebHost method so you had to have an IDbContextFactory. The change to support Program.BuildWebHost is in preview2.