In this chapter, you will set up Entity Framework (EF) and get familiar with how it works. To work with EF, you must install the proper services, either manually in the .csproj file or by using the NuGet manager.
When the services have been installed and configured in the Startup class, you need to add a data context class that inherits from the DbContext class. This class will be the context that you use to interact with the database. To add a table to the database, the table’s entity class must be added as a DbSet property in the context class.
When the services are installed and configured in the Startup class, you create the first migration by using the Package Manager Console and the Add-Migration command. When the initial migration has been added, the database can be generated with the Update-Database command.
If you make any changes to the database, like adding or changing columns or tables, then you must execute the Add-Migration and Update-Database commands again for the application to work properly.
In previous versions you had to install Entity Framework NuGet packages to create and use a database. In ASP.NET Core 2.2 those NuGet packages are installed as part of the Microsoft.AspNetCore.App NuGet package.
The setup for User Secrets has been incorporated into the new BuildWebHost method in the Program.cs file, which means that you no longer have to add any configuration for it in the Startup class. You can use User Secrets to store sensitive data locally in a file called secrets.json, which is stored outside the solution folder structure and is never committed to the source code repository, if you use that. You will store the connection string to the database securely in the secrets.json file.
Now that the NuGet packages have been installed, you can add a class called VideoDbContext that inherits form the DbContext class. This class will be your connection to the database. It defines the entity classes as DbSet properties, which are mirrored as tables in the database.
For the AddDbContext method to be able to add the context to the services collection, the VideoDbContext must have a constructor with a DbContextOptions<VideoDbContext> parameter, which passes the parameter object to its base constructor. The OnModelCreating method must be overridden to enable Entity Framework to build the entity model for the database.
public class VideoDbContext : DbContext { }
public DbSet<Video> Videos { get; set; }
public VideoDbContext(DbContextOptions<VideoDbContext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
The complete code for the VideoDbContext class:
public class VideoDbContext : DbContext
{
public DbSet<Video> Videos { get; set; }
public VideoDbContext(DbContextOptions<VideoDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
Before the initial migration can be applied, you have to configure Entity Framework to use the VideoDbContext, and read the connection string from the secrets.json file. Using the secrets.json file has two purposes: It stores the connection string in a safe place that is not checked into source control. It also renders the appsettings.json obsolete for storing secret or sensitive data, which is a good thing, since it is checked into source control.
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=VideoCoreIntroDb;Trusted_Connection=True;MultipleActiveResultSets=true"
}
var conn = Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<VideoDbContext>(options =>
options.UseSqlServer(conn));
The complete code for the secrets.json file:
The complete code for the secrets.json file:{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=VideoCoreIntroDb;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
Note that the DefaultConnection property value should be one line of code.
The complete code for the Startup class’s ConfigureServices method:
public void ConfigureServices(IServiceCollection services)
{
var conn = Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<VideoDbContext>(options =>
options.UseSqlServer(conn));
services.AddMvc();
services.AddSingleton<IMessageService,
ConfigurationMessageService>();
services.AddSingleton<IVideoData, MockVideoData>();
}
To add the initial migration and create the database, you execute the Add-Migration and Update-Database commands in the Package Manager Console (View-Other Windows-Package Manager Console).
When the Add-Migration command has been successfully executed, a new folder called Migrations will appear in the project. The current and all future migrations will be stored in this folder.
If you encounter the error message No parameterless constructor was found on 'VideoDbContext': Either add a parameterless constructor to 'VideoDbContext' or add an implementation of 'IDbContextFactory<VideoDbContext>' in the same assembly as 'VideoDbContext', then check that your connection string in secrets.json is correct and that it is being loaded in the Startup class, before doing any other troubleshooting.
To use the database in the application, you can implement the IVideoData interface in a new service component class. Then, you change the service registration in the ConfigureServices method in the Startup class to create instances of the new component.
Let’s begin by implementing the SqlVideoData class that will communicate with the database through the VideoDbContext.
private
readonly VideoDbContext _db;
public SqlVideoData(VideoDbContext db)
{
_db = db;
}
public class SqlVideoData : IVideoData
public void Add(Video
newVideo)
{
_db.Add(
newVideo);
_db.SaveChanges();
}
public Video Get(int id)
{
return _db.Find<Video>(id);
}
public IEnumerable<Video> GetAll()
{
return _db.Videos;
}
services.AddScoped<IVideoData, SqlVideoData>();
The complete code in the SqlVideoData class:
public class SqlVideoData : IVideoData
{
private readonly VideoDbContext _db;
public SqlVideoData(VideoDbContext db)
{
_db = db;
}
public void Add(Video newVideo)
{
_db.Add(newVideo);
_db.SaveChanges();
}
public Video Get(int id)
{
return _db.Find<Video>(id);
}
public IEnumerable<Video> GetAll()
{
return _db.Videos;
}
}
The complete code in the ConfigureServices method:
public void ConfigureServices(IServiceCollection services)
{
var conn = Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<VideoDbContext>(options =>
options.UseSqlServer(conn));
services.AddMvc();
services.AddSingleton<IMessageService,
ConfigurationMessageService>();
services.AddScoped<IVideoData, SqlVideoData>();
}
In this chapter, you installed the Entity Framework and User Secrets services in the Setup class.
You also added a DbContext class that communicates with the database, and a new service component class that implements the IVideoData Interface, as a separation between the DbContext and the application.
Finally, you added a new video to the database using the Create view, and verified that it had been added to the database.
Join our mailing list to receive the latest news and updates from our team.
Don't worry, your information will not be shared.
50% Complete
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.