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.