.NET C# - Entity Framework Core Review Note
What is Entity Framework Core (ORM)
Framework core is a type of ORM
and that stands for Object Relational Mapping
.
Mapping some group of objects to the datastore.
Entity Framework Core simplifies database interactions in .NET applications by providing a convenient and flexible ORM framework, supporting various databases, and offering features like migration support and cross-platform compatibility.
In simpler terms, when using Entity Framework Core (EF Core) in our application, it acts as a bridge between our code and the database.
-
Database Schema:
- In a relational database, the schema defines the structure of the database, including tables, fields, and relationships.
- Tables represent entities (e.g., users, products), and relationships define how these entities are related.
-
ORM Framework (e.g., Entity Framework Core):
- Acts as a bridge between the application code and the database.
- Provides an abstraction layer, allowing developers to work with database entities using programming objects in their code.
-
Mapping:
- ORM frameworks map application objects to database tables. Each class in your code corresponds to a table in the database.
- Relationships between objects in your code mirror the relationships between tables in the database.
-
Object-Relational Mapping (ORM):
- ORM simplifies database interactions by letting developers work with objects in their code rather than writing raw SQL queries.
- When the application runs, the ORM framework handles the translation between the application’s objects and the database schema.
-
In-Memory Mapping:
- The ORM maintains an in-memory mapping between application objects and database entities.
- This mapping allows seamless communication between the application and the database without developers needing to deal directly with SQL.
-
Simplified Interaction:
- Developers can focus on working with objects in their code, using familiar programming constructs.
- Changes to the database schema (e.g., adding a new field) can be handled through the ORM’s migration tools, simplifying the process of keeping the database schema in sync with the application code.
-
Migration
= a way to create all of the tables in the database or add another new table in the database or change the table columns or the relationships.
Nuget Packages for EF
- To work with
ASP.NET CORE
and use Entity Framework (EF), we need to install a few Nuget packages.- Entity framework Core SQL Server
- For migration:
- EntityFrameworkCore.Tools
- EntityFrameworkCore.Design
Create Database Context
In the example code below, the DbSet
is actually a table in our database. Each property in the Shirt
class represents for different columns in that table.
// Data/ApplicationDbContext.cs
public class ApplicationDbContext: DbContext
{
public DbSet<Shirt> Shirts {get; set;}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
Table Shirt
By default, the ShirtId
or Id
will be the primary key (PK) in the table.
public class Shirt
{
public int ShirtId {get; set;}
...
}
Seed Data
// Data/ApplicationDbContext.cs
public class ApplicationDbContext: DbContext
{
public ApplicationDbContext(DbContextOptions options): base(options)
{
}
public DbSet<Shirt> Shirts {get; set;}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// data seeding
modelBuilder.Entity<Shirt>().HasData(
new Shirt{ShirtId = 1, ...<other properties>}
)
}
}
Db Migration
Again, migration is like an operation to update the actually Db according to the DBContext
class. If there is no existing table, the first migration is actually creating the entire new Database and tables and all relationship in SQL Server.
Note: we can use launchSettings.json
to set up our environment inside our project. This file contains the information for setting up schemes(Http, https), port, etc.
Specify connections string
// appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "Server=YourServer;Database=YourDatabase;User=YourUsername;Password=YourPassword;"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Add middleware to use EF
// program.cs
var builder = WebApplication.CreateBuilder(args);
#region SET UP DBCONTEXT HERE
builder.Services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))
});
#endregion
// Add services to the container
builder.Services.AddController();
var app = builder.Build();
// Configure the HTTP request pipeline
app.UseHttpsRedirection();
app.MapControllers();
app.Run();
Run migration
In visual studio, Tools > NuGet Package Manager > Package Manager Console
Run the following command in the Package Manager Console to generate the scripts to create tables and relationship.
Add-Migration Init
After executing the command above, we should be able to see a new folder called Migrations
generated.
If we inspect the autogenerated files in Migrations
folder, we notice that there are 2 main method Up
and Down
In the context of Entity Framework Core migrations, the Up
method is responsible for applying changes to the database schema, typically by creating or modifying database objects. The Down
method, on the other hand, is designed to revert these changes, allowing for the rollback of migrations.
In scenarios where there is a single table or entity within the database, the Up
method, during the initial migration, will generate SQL statements to create the corresponding table and apply any specified configurations. Conversely, the Down
method, associated with the initial migration’s rollback, will contain SQL statements to drop the created table, effectively undoing the changes introduced by the Up
method.
It’s essential to recognize that the Up
and Down
methods within a migration class encapsulate the actions needed to transition the database schema forward and backward, respectively, with the aim of maintaining consistency throughout the application’s development lifecycle.
Next, we need to run the update-database
command in the Package Manager Console or the .NET CLI. It applies the pending migrations to the database. This involves executing the Up
method in each migration.
update-database Init
Inject the DBContext to Controller
In order to use EFCore
in our controller, say ShirtsController
, we need to do the dependency injection in the constructor as following.
[ApiController]
[Route("api/[controller]")]
public class ShirtsController: ControllerBase
{
private readonly ApplicationContext db;
public ShirtsController(ApplicationContext db)
{
this.db = db;
}
...
}
When we use ToList()
, Entity Framework Core promptly queries the database and transforms the retrieved data into a list of Shirt
objects.
For example, if we have the GetShirts
API endpoint in our controller, we could do this to retrieve data from database.
[ApiController]
[Route("api/[controller]")]
public class ShirtsController: ControllerBase
{
private readonly ApplicationContext db;
public ShirtsController(ApplicationContext db)
{
this.db = db;
}
[HttpGet]
public IActionResult GetShirts()
{
return Ok(db.Shirts.ToList())
}
}
[TypeFilter] attribute in ASP.NET note
This attribute is used to apply a custom action filter to a controller or action method. If you are looking for a custom action filter attribute, you would typically create a custom class that implements IActionFilter
or inherits from ActionFilterAttribute
. The [TypeFilter]
attribute is then used to associate this custom action filter with a controller or action method.
For example,
- Create a Custom Action Filter:
using Microsoft.AspNetCore.Mvc.Filters;
public class CustomActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// Code to be executed before the action method
}
public void OnActionExecuted(ActionExecutedContext context)
{
// Code to be executed after the action method
}
}
- Apply the Custom Action Filter using
[TypeFilter]
:
using Microsoft.AspNetCore.Mvc;
[TypeFilter(typeof(CustomActionFilter))]
public class YourController : Controller
{
// Your controller actions
}
Note: Use [TypeFilter]
when you want to apply a custom action filter that you’ve created as a class to a specific controller or action method in ASP.NET MVC
or ASP.NET Core
. It provides a way to specify custom action filter types at the class level.
To add new record
Simply, we can the Add
and SaveChanges
from EFCore to add the new record
Example:
[HttpPost]
public IActionResult CreateShirt([FromBody]Shirt shirt)
{
this.db.Shirts.Add(shirt);
this.SaveChanges();
return CreatedAtRoute(
nameof(GetShirtsById),
new { id = shirt.ShirtId },
shirt);
}
To delete record
We invoke the Remove
and SaveChanges
from EFCore.
Example:
[HttpDelete("{id}")]
public IActionResult DeleteShirt(int id)
{
var shirtToDelete = HttpContext.Items["shirt"] as Shirt;
db.Shirts.Remove(shirtToDelete);
db.Shirts.SaveChanges();
return Ok(shirtToDelete);
}