12

I am using Visual Studio 2022 Preview and .NET 6 SDK.

Here I am creating a webAPI project with 2 layers. api project (Bgvsystem.webAPI) class library (BgvSystem.Persistance)

NuGet packages-

Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 6.0.0-rc.1.21452.10

Install-Package Microsoft.EntityFrameworkCore.Tools -Version 6.0.0-rc.1.21452.10

Install-Package Microsoft.VisualStudio.Web.CodeGeneration.Design -Version 6.0.0-rc.1.21464.1

When I try to add a controller using scaffolding, I get the below error

There was an error running the selected code generator: unable to resolve service for type 'microsoft.entityframeworkcore.dbcontextoption.. While attempting to activate Dbcontext in  .net 6 and visual studio 2022 preview

enter image description here

How to resolve this? Please help with this.

tRuEsAtM
  • 3,517
  • 6
  • 43
  • 83
GOPAL SHARMA
  • 657
  • 2
  • 12
  • 37
  • I have same problem here..will try this https://stackoverflow.com/questions/70516934/not-able-to-scaffold-a-controller-in-asp-net-6-core-web-api – Laco Jan 02 '22 at 17:43

7 Answers7

15

You can create a dbcontext factory class in same folder with your ApplicationDbContext class. This factory class creates ApplicationDbContext at design time and scaffolding runs correctly.

Source: https://github.com/dotnet/Scaffolding/issues/1765

public class ApplicationDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext>
{
    public ApplicationDbContext CreateDbContext(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
        optionsBuilder.UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Database=EcommerceDb;Trusted_Connection=True;MultipleActiveResultSets=true");
    
        return new ApplicationDbContext(optionsBuilder.Options);
    }
}
carloswm85
  • 1,396
  • 13
  • 23
Simant
  • 3,142
  • 4
  • 32
  • 61
  • 4
    This answer fixed it for me, all others did not. +1 – Swedo Aug 23 '22 at 11:34
  • 1
    Thanks a lot, it worked for .net7 with VS 2023 – Satyajit Apr 01 '23 at 16:20
  • Additional information can be found here: https://learn.microsoft.com/en-us/ef/core/cli/dbcontext-creation?tabs=dotnet-core-cli#from-a-design-time-factory – carloswm85 Jun 18 '23 at 00:07
  • From the link above: "You can also tell the tools how to create your DbContext by implementing the `Microsoft.EntityFrameworkCore.Design.IDesignTimeDbContextFactory` interface: If a class implementing this interface is found in either the same project as the derived `DbContext` or in the application's startup project, the tools bypass the other ways of creating the DbContext and use the design-time factory instead. A design-time factory can be especially useful if you need to configure the `DbContext` differently for design time than at run time." – carloswm85 Jun 18 '23 at 00:10
5

After struggling for 3 days, finally I found the mistake and fixed that.

Actually I had to put connection string in MyApp.Persistance.DbContextClass as below

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                optionsBuilder.UseSqlServer("Data Source=DESKTOP-SV8GPJ2\\SQLEXPRESS;Initial Catalog=StarterAppDB;Persist Security Info=True;User ID=sa;Password=Admin@1234");
            }
        }

Then it worked fine.

GOPAL SHARMA
  • 657
  • 2
  • 12
  • 37
5

You can create a dbcontext factory class in same folder with your ApplicationDbContext class. This factory class creates ApplicationDbContext at design time and scaffolding runs correctly.

public class ApplicationDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext>
{
        public ApplicationDbContext CreateDbContext(string[] args)
        {
            var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
            optionsBuilder.UseSqlServer("Server=YourServer; Database=YourDb; Integrated Security=true; MultipleActiveResultSets=true; Trusted_Connection=True");

            return new ApplicationDbContext(optionsBuilder.Options);
        }
}
Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
  • This worked for me. I also added sqlOption => sqlOption.UseNetTopologySuite() after the connection string as I am persisting geography info to the DB. Otherwise, scaffolding throws an error: 'Point.UserData' could not be mapped because it is of type 'object'... – Corey Jensen Nov 23 '22 at 07:56
4

In case of .NET 6

Can you try like this

Program.cs

builder.Services.AddDbContext<YourDbContext>(options =>
     options.UseSqlServer("name=ConnectionStrings:DefaultConnection"));

appsettings.json

"ConnectionStrings": {
   "DefaultConnection": "Server=YourServer; Database=YourDb; Integrated Security=true; MultipleActiveResultSets=true; Trusted_Connection=True"
}

YourDbContext.cs

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if (!optionsBuilder.IsConfigured)
    {
        optionsBuilder.UseSqlServer("Server=YourServer; Database=YourDb; Integrated Security=true; MultipleActiveResultSets=true; Trusted_Connection=True");
    }
}
Peter Csala
  • 17,736
  • 16
  • 35
  • 75
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 18 '22 at 09:38
0

You need to add the DBContext to service collection in startup.cs file or pass as constructor BGvSystemContext class.

Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
0

If you don't need the options builder for additional configuration you can dependency inject IConfiguration and use that to pass the connection string inside of OnConfiguring. This will solve the problem with ef code generation.

public class ApplicationDbContext : DbContext
{
    private IConfiguration _config;
    public ApplicationDbContext(IConfiguration config) 
    {
        _config = config;
    }
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(_config.GetConnectionString("DefaultConnection"));
    }
}

And in startup you can use the paramaterless constructor for your db context instead of options builder

0

I am using N-Tier Architecture and asp net Area, so along with your ApplicationDbContext class add another class (DataContextFactory) class with following code Good luck!

public class DataContextFactory : IDesignTimeDbContextFactory<AppDbContext>
{
    public AppDbContext CreateDbContext(string[] args)
    {
        var configuration = new ConfigurationBuilder()
         .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
         .AddJsonFile("appsettings.json")
         .Build();

        var optionsBuilder = new DbContextOptionsBuilder<AppDbContext>();
        optionsBuilder.UseSqlServer(configuration.GetConnectionString("KasicaConnection"));

        return new AppDbContext(optionsBuilder.Options);
    }