Asp.net core + entity framework


Start point

In the previous article we have learned how to works with views in asp.net core mvc. Now, I want to add entity framework core support to my application.

First step is installing ef core package with sqlite provider.

Install-Package Microsoft.EntityFrameworkCore.Sqlite

Secondly, let’s add new folder Data in the root of project. Then, add new class with name MoviesContext.cs and following content

public class MoviesContext : DbContext
{
    public MoviesContext(DbContextOptions options) : base(options)
    {
    }

    public DbSet<Movie> Movies { get; set; }
}

Also, you have to change in Startup.cs method ConfigureServices.

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<MoviesContext>(options =>
    {
        options.UseSqlite("Filename=movies.db");
    });
    services.AddMvc();            
}

Now, we can execute command add-migration first in Package Manager console in visual studio.

In the root of your project must be created Migrations folder with your first migration. As you can see migration contains 2 methods.

 public partial class first : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(
            name: "Movies",
            columns: table => new
            {
                Id = table.Column<int>(nullable: false)
                    .Annotation("Sqlite:Autoincrement", true),
                Poster = table.Column<string>(nullable: true),
                Name = table.Column<string>(nullable: true),
                Author = table.Column<string>(nullable: true),
                Genre = table.Column<string>(nullable: true),
                CreatedAt = table.Column<DateTime>(nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Movies", x => x.Id);
            });
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropTable(
            name: "Movies");
    }
}

Up method creates table with properties from Movie class

To apply this migration to database, we need to execute next command.

update-database

After succesfull execution of this command. There will be new file movies.db in the root of your project. This is your sqlite database. Hovewer, you can use any database you want. Just select another ef provider.

In the previous article, we added initial data of our movies storage. Let’s add this data to our newly created db using ef. We should ovveride OnModelCreating method in our db context.

public class MoviesContext : DbContext
{
    public MoviesContext(DbContextOptions options) : base(options)
    {
    }

    public DbSet<Movie> Movies { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Movie>().HasData(new Movie
        {
            Id = -1,
            Author = "Todd Phillips",
            Genre = "Crime , Drama , Thriller",
            Name = "Joker",
            Poster = "https://dz7u9q3vpd4eo.cloudfront.net/admin-uploads/posters/mxt_movies_poster/joker_dabf394a-d4f2-4b68-90e2-011ed6b54012_poster.png?d=270x360&q=20",
            CreatedAt = new DateTime(2019, 10, 3)
        },
        new Movie
        {
            Id = -2,
            Author = "David Leitch",
            Genre = "Action , Adventure",
            Name = "Fast & Furious Presents: Hobbs & Shaw",
            Poster = "https://dz7u9q3vpd4eo.cloudfront.net/admin-uploads/posters/mxt_movies_poster/fast-furious-presents-hobbs-shaw_14d1ab4f-c90c-46d1-9e04-f7d69f285ebd_poster.png?d=270x360&q=20",
            CreatedAt = new DateTime(2019, 8, 2)
        },
        new Movie
        {
            Id = -3,
            Author = "Jon Favreau",
            Genre = "Adventure , Animation , Drama , Family , Musical",
            Name = "The Lion King",
            Poster = "https://dz7u9q3vpd4eo.cloudfront.net/admin-uploads/posters/mxt_movies_poster/the-lion-king_3904aadc-3a07-4836-892f-763b2dfdeea3_poster.png?d=270x360&q=20",
            CreatedAt = new DateTime(2019, 7, 19)
        },
        new Movie
        {
            Id = -4,
            Author = "Joachim Rønning",
            Genre = "Adventure , Family , Fantasy",
            Name = "Maleficent: Mistress of Evil",
            Poster = "https://dz7u9q3vpd4eo.cloudfront.net/admin-uploads/posters/mxt_movies_poster/maleficent-mistress-of-evil_c8507e61-a6b3-404d-b8c5-df6f74bc62be_poster.png?d=270x360&q=20",
            CreatedAt = new DateTime(2019, 10, 18)
        });
    }
}

Since, we changed db context , we must add new migration again.

add-migration dataSeed

Probably, you noticed that we used negative ids, the reason is otherwise entity framework says The seed entity for entity type ‘Movie’ cannot be added because a non-zero value is required for property ‘Id’. Consider providing a negative value to avoid collisions with non-seed data.

Don’t forget update-database command.

Finnaly, we should change our MoviesControler to using database as storage for movies.

public class MoviesController : Controller
{
    private readonly MoviesContext _dbContext;

    public MoviesController(MoviesContext dbContext)
    {
        _dbContext = dbContext;
    }

    public async Task<IActionResult> Index()
    {
        var movies = await _dbContext.Movies.ToListAsync();
        return View(movies);
    }

    [HttpGet]
    public IActionResult Add()
    {            
        return View();
    }

    [HttpPost]
    public async Task<IActionResult> Add(Movie movie)
    {
        

        _dbContext.Movies.Add(movie);
        await _dbContext.SaveChangesAsync();

        var movies = await _dbContext.Movies.ToListAsync();

        return View("Index",movies);
    }

    public async Task<IActionResult> Search(string text)
    {
        text = text.ToLower();
        var searchedMovies = await _dbContext.Movies.Where(movie => movie.Name.ToLower().Contains(text)
                                        || movie.Genre.ToLower().Contains(text)
                                        || movie.Author.ToLower().Contains(text))
                                    .ToListAsync();
        return View("Index", searchedMovies);
    }

}

Let’s run and check if all is working. Go to /movies and try to add new movie on movies/add. If you stop your app, your data should be persisted. And after restarting it, you can see your newly added movies still here.

Conclusion

We added Entity framework support to our application. Also, learned about migrations and why we need them during our model is changed. We made sure, that ef allows to easily work with any relation database.

Buy Me A Coffee

Related Posts

Avoid reflections of mappers and let Mapster generate mappers for you

Mapster generating tool for onion application

Predict Bitcoin price with ML.net

Live time series coin price predictor with machine learning

Throw exceptions from backend to frontend with blazor

One of advantages of using same code language on both frontend and backend

How to avoid violating of SOLID principles while extending service behaviours

Step by step extending service behaviour with decorator pattern respecting SOLID

Blazor render optimization

Best practices

.Net 6 brings application state to blazor webassembly server prerender

It kills strange blinking on screen

Must have libraries for blazor

List of best nuget packages

Blazor virtualize component

Lazy loading of big lists. Rendering optimization.

Blazor grpc - comunication optimization

Smaller and faster requests to your backend from blazor wasm

Free database for your blazor app

Don't pay for the cloud