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.
