locked
error trying to use EF core code first RRS feed

  • Question

  • User1571524970 posted

    I am trying to use entity framework core code first, with an external sql server database hosted on AWS RDS. My aim is for EF to create my model database/tables automatically the first time I use Swagger to create an object. Currently, I am trying to enable migrations for my project before I allow EF code first to create the databases. Although when I try to Enable-Migrations I get an error: "The context type 'FitnessTrackerAPIContext' was not found in the assembly 'FitnessTrackerAPI'." As you can see from the below picture, the 'FitnessTrackerAPIContext' is in the 'FitnessTrackerAPI' so I am not sure why I am getting this error.

    err

    I am not quite sure if all my settings for EF core are correct s this is my first time using it.

    Context:

    namespace FitnessTrackerAPI.Data
    {
        public class FitnessTrackerAPIContext : DbContext
        {
            public FitnessTrackerAPIContext (DbContextOptions<FitnessTrackerAPIContext> options)
                : base(options)
            {
            }
    
            public DbSet<FitnessTracker.UserData> Users { get; set; }
    
            public DbSet<FitnessTracker.WorkoutData> Workouts { get; set; }
        }
    }

    I have added the following to Startup.cs:

      services.AddDbContext<FitnessTrackerAPIContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("FitnessTrackerAPIContext")));

    My connection string in appsettings.json:

     "ConnectionStrings": {
        "FitnessTrackerAPIContext": "Server=fitnessapi.clxnbxbuoxx1.eu-west-1.rds.amazonaws.com,1433;User ID=XXXXX;Password=XXXXX; Initial Catalog=fitnessapi; Database=fitnessapi; Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"

    Do I need to add any other code? In program.cs or so? This is program.cs currently:

    namespace FitnessTrackerAPI
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                CreateHostBuilder(args).Build().Run();
            }
    
            public static IHostBuilder CreateHostBuilder(string[] args) =>
                Host.CreateDefaultBuilder(args)
                    .ConfigureWebHostDefaults(webBuilder =>
                    {
                        webBuilder.UseStartup<Startup>();
                    });
        }
    }

    Any advice would be appreciated.

    Friday, April 3, 2020 12:10 PM

All replies

  • User475983607 posted

    darego

    Do I need to add any other code? In program.cs or so?

    Yes, you need to add code to invoke pending migrations.

            private void InitializeDatabase(IApplicationBuilder app)
            {
                using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
                {
                    var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
                    context.Database.Migrate();
    
                }
            }

    Call the method from startup.cs.

            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                //Apply pending migrations
                InitializeDatabase(app);

    This configuration causes migrations to run when the application starts.

    Friday, April 3, 2020 12:41 PM
  • User1571524970 posted

    Thanks a lot mgerbhard. Can I confirm, I need InitializeDatabase() in the program.cs file outside of Main, and call it  from Startup.cs in Configure? e.g.

    Startup.cs

     // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                //Apply pending migrations
                InitializeDatabase(app);

    Program.cs

    public class Program
        {
            public static void Main(string[] args)
            {
    
                CreateHostBuilder(args).Build().Run();
            }
    
            private void InitializeDatabase(IApplicationBuilder app)
            {
                using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
                {
                    var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
                    context.Database.Migrate();
    
                }
            }
    
            public static IHostBuilder CreateHostBuilder(string[] args) =>
                Host.CreateDefaultBuilder(args)
                    .ConfigureWebHostDefaults(webBuilder =>
                    {
                        webBuilder.UseStartup<Startup>();
                    });
        }

    Friday, April 3, 2020 1:33 PM
  • User1571524970 posted

    it seems to be working now; i put the InitializeDatabase() method above the Configure() method in Startup.cs

     private void InitializeDatabase(IApplicationBuilder app)
            {
                using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
                {
                    var context = serviceScope.ServiceProvider.GetRequiredService<FitnessTrackerAPIContext>();
                    context.Database.Migrate();
                }
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                //Apply pending migrations
                InitializeDatabase(app);

    Shouldn't EF code first create my tables now when I try access the API? I used swagger to post an object to the API and got the following 500 server error:

    Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
     ---> Microsoft.Data.SqlClient.SqlException (0x80131904): Invalid object name 'Users'.

    It seems like EF isn't automatically creating my tables. fitnessapi database has no tables:

    empty

    Friday, April 3, 2020 2:23 PM
  • User711641945 posted

    Hi darego,

    It seems like EF isn't automatically creating my tables. fitnessapi database has no tables:

    That is because you do not have migration file in your project.

    A simple way is to run the command on PMC(Package Manager Console):

    PM>add-migration init

    Then you could run the app by using your code(InitializeDatabase(app)) to apply the migration,or run the following command which could also apply the migration:

    PM>update-database

    Reference:

    https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/?tabs=vs

    Best Regards,

    Rena

    Monday, April 6, 2020 7:26 AM