I'm building an ASP.NET Web Api with simple CRUD operations and a Database which should be generated using EF Code First and Migrations. In terms of the structure of the project, I am using ASP.NET Web API as the main project and a class library as the database context.
This is what I have in my Class library:
Database Context:
using Microsoft.EntityFrameworkCore;
using MyApp.Database.Models;
namespace MyApp.Database.Context;
public class MyAppContext : DbContext
{
public MyAppContext(DbContextOptions<MyAppContext> options) : base(options) { }
public virtual DbSet<Booking> Bookings { get; set; }
public virtual DbSet<Person> Persons { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Seed();
base.OnModelCreating(modelBuilder);
}
}
Database Models:
namespace MyApp.Database.Models;
public class Booking
{
public int Id { get; set; }
public int Week { get; set; }
public int DayOfWeek { get; set; }
public int Hour { get; set; }
public int PersonId { get; set; }
public virtual Person Person { get; set; }
}
using System.Collections.Generic;
namespace MyApp.Database.Models;
public class Person
{
public int Id { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public int Age { get; set; }
public virtual IEnumerable<Booking> Bookings { get; set; }
}
Besides that I have a class in the library called SeederExtension which has an Extension method that should Seed the database
using Microsoft.EntityFrameworkCore;
using MyApp.Database.Models;
namespace MyApp.Database;
public static class SeedExtension
{
public static void Seed(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>().HasData(new Person
{
Id = 1,
Firstname = "John",
Lastname = "Doe",
Age = 28,
});
}
}
In my ASP.NET Web API project I register the Database context in my Program.cs with the following code.
builder.Services.AddDbContext<MyAppContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("MyAppDb"));
});
The problem is now when I want to add migrations. I go to the Package Manager Console and navigate to the Class Library project where my Database Context is located. Then I enter this command to add a migration: dotnet ef migrations add "Init" which produces this error then: Unable to create an object of type 'MyAppContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
I've seen a lot of tutorial where this worked but unfortunately after hours of research I haven't found a working solution.
I'm using .net6 and the following NuGet packages in my class library
- Microsoft.EntityFrameworkCore (version 7.0.2)
- Microsoft.EntityFrameworkCore.SqlServer (version 7.0.2)
- Microsoft.EntityFrameworkCor.Tools (version 7.0.2)
And here is my connectionString if it helps:
{
"ConnectionStrings": {
"MyAppDb": "server=(LocalDB)\\mssqllocaldb;database=MyAppDB;integrated security=True"
}
}
CodePudding user response:
Try adding a parameterless constructor: public MyAppContext() {}
.
Options are to pass to constructor by DI based on your ConfigureService in the Startup class. 'Add migration' shouldn't know what options to pass since it does not use the Startup.
CodePudding user response:
If you take a look at here
https://learn.microsoft.com/en-us/ef/core/managing-schemas/migrations/projects?tabs=dotnet-core-cli
Note the difference in your command and selecting the database csproj. In the docs it has:
dotnet ef migrations add NewMigration --project WebApplication1.Migrations
The connection string comes from your main project. Again, from the docs:
services.AddDbContext<ApplicationDbContext>(
options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection"),
x => x.MigrationsAssembly("WebApplication1.Migrations")));
I have, obviously, just pasted in the above from the docs. You will need to match with your own projects.
If you instead run the migrations using just the database project, I am not sure it would pick up the connection string out the web api project.