Aspnetcore.docs: Suggestion to use EF 2.1 Seed feature on MvcMovieContext instead

Created on 25 Oct 2018  Â·  10Comments  Â·  Source: dotnet/AspNetCore.Docs

EF Core 2.1 brings back seed support by overriding the OnModelCreating method of a database Context class, same way as the "old" EF does. So it’s not required anymore to create a separate Initialize class and call it on Program.cs as the current tutorial does, the MvcMovieContext is now able to seed data (the same way as the old MVC 5 tutorials does). Moreover, I personally believe it would reduce the amount of code necessary to reach the goal of seeding data and consequently will decrease the complexity to beginners. I believe Introducing EF 2.1 seed capability on the tutorial would also be didactic.

What about updating the "Seed the database" section to seed data through MvcMovieContext database context class by overriding the OnModelCreating method?

Thanks so much.


Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

P2 Source - Docs.ms

All 10 comments

@divega what's the best practice to seed the DB from an ASP.NET Core app?

In order to update the Create an MVC web app tutorial to use EF 2.1 Seed feature in the MvcMovieContext instead of a separate SeedData class, some updates in the tutorial's code should be made. Instructions in the Work with SQL Server LocalDB and Add a new field sections are also required to be updated.

By using EF 2.1 Seed feature on MvcMovieContext class, the MvcMovieContext.cs would be:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

namespace MvcMovie.Models
{
    public class MvcMovieContext : DbContext
    {
        public MvcMovieContext (DbContextOptions<MvcMovieContext> options)
            : base(options)
        {
        }

        public DbSet<MvcMovie.Models.Movie> Movie { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Movie>().HasData(
                new Movie
                {
                    ID = 1,
                    Title = "When Harry Met Sally",
                    ReleaseDate = DateTime.Parse("1989-1-11"),
                    Genre = "Romantic Comedy",
                    Price = 7.99M
                },

                new Movie
                {
                    ID = 2,
                    Title = "Ghostbusters ",
                    ReleaseDate = DateTime.Parse("1984-3-13"),
                    Genre = "Comedy",
                    Price = 8.99M
                },

                new Movie
                {
                    ID = 3,
                    Title = "Ghostbusters 2",
                    ReleaseDate = DateTime.Parse("1986-2-23"),
                    Genre = "Comedy",
                    Price = 9.99M
                },

                new Movie
                {
                    ID = 4,
                    Title = "Rio Bravo",
                    ReleaseDate = DateTime.Parse("1959-4-15"),
                    Genre = "Western",
                    Price = 3.99M
                }
            );
        }
    }
}

The Program.cs file would also change for its initial implementation:

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using Microsoft.EntityFrameworkCore;
using MvcMovie.Models;
using MvcMovie;

namespace MvcMovie
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>();
    }
}

It also requires a new Migration to be generated and applied in order to insert the seed data in the db.

@dannevesdantas great idea. We'll take this approach in the next upgrade (soon). cc @tdykstra

cool @Rick-Anderson! I'm glad to be able to help.

@Rick-Anderson @scottaddie @tdykstra Since the scenario ...

requires a new Migration to be generated and applied in order to insert the seed data in the db.

Do we want to do this in sample apps/topics where migrations aren't in use? It adds a layer of tedious complexity to our normal ✨ Just Run It!:tm: ✨ samples.

@divega should we use protected override void OnModelCreating(ModelBuilder modelBuilder) (as shown in the previous code) and migrations to seed the DB?

@dannevesdantas thanks for your suggestion, it worked very well.
I have few notes:

  1. The ID field inside OnModelCreating() method should be rewritten as "Id" according to Movie.cs in the tutorial.
  2. There is no way to check for any existing data while creating the model, thus, the tutorial should either use SSOX to empty the table or drop-database MPC command.
  3. What I liked about your solution for seeding is that it avoids modifying Program.cs file, which makes the code much simpler. Thank you.

@Rick-Anderson sorry I missed it when you mentioned me before. I don't know/remember in detail how the tutorial uses the seed data. I think using model data seeding feature would be a good idea as long as:

  1. The usage of the data in the tutorial doesn't fall into any of the scenarios described in https://docs.microsoft.com/ef/core/modeling/data-seeding#limitations-of-model-seed-data.
  2. The tutorial doesn't show how to apply the data programmatically (in general, a pit of failure) but rather using migration commands or through generating and deploying a SQL script.

You're right @shadinamrouti! "Id" fits the convention. I've also noticed that in the old MVC 6 getting started tutorial SSOX was used for deleting the database, so I think it looks a good option, as beginners could learn how to use SSOX also while following the tutorial.

We've decided to keep the current approach for simplicity.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wgutierrezr picture wgutierrezr  Â·  3Comments

royshouvik picture royshouvik  Â·  3Comments

aaron-bozit picture aaron-bozit  Â·  3Comments

fabich picture fabich  Â·  3Comments

danroth27 picture danroth27  Â·  3Comments