Back to: ASP.NET Core Tutorials For Beginners and Professionals
CRUD Operations in Entity Framework Core (EF Core)
In this article, I am going to discuss CRUD Operations in Entity Framework Core (EF Core). Please read our previous article, where we discussed Database Connection String in Entity Framework Core. We will work with the same example we have worked on so far.
CRUD Operations in Entity Framework Core (EF Core):
CRUD Operation means we need to perform Create, Retrieve, Update, and Delete Operations. In order to perform the Insert, Update, and Delete operations in Entity Framework Core, we have two persistence scenarios, i.e., connected and disconnected.
In the connected scenario, the same DbContext instance is used for retrieving and saving the entities, whereas this is different in the disconnected scenario. In this article, we will learn about performing database CRUD operations in the connected scenario, and in our upcoming articles, we will discuss how to perform CRUD Operations in a disconnected scenario.
An entity that contains data in its scalar property will be either INSERTED, UPDATED, or DELETED, based on the State of the Entity. The Entity Framework builds and executes the INSERT, UPDATE, and DELETE SQL statements for the entities whose Entity State is Added, Modified, and Deleted, respectively, when the SaveChanges() method is called on the DbContext instance. The following diagram shows the connected scenario’s CUD (Create, Update, Delete) operations.
Note: In the connected scenario, an instance of DbContext class keeps track of all the entities, and when an entity is created, modified, or deleted, it automatically sets the appropriate State for the entity.
Enabling EF Core Logging:
We often need to log the generated SQL Script and Change Tracking information for debugging purposes in EF Core. Entity Framework Core logging automatically integrates with the logging mechanisms of .NET Core.
Entity Framework Core (EF Core) simple logging can be used to obtain logs while developing and debugging applications easily. This form of logging requires minimal configuration and no additional NuGet packages.
EF Core logs can be accessed from any application through the use of the LogTo method when configuring the DbContext instance. This configuration is commonly done in an override method of DbContext.OnConfiguring. So, modify the EFCoreDbContext class as follows.
using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; namespace EFCoreCodeFirstDemo.Entities { public class EFCoreDbContext : DbContext { //Constructor calling the Base DbContext Class Constructor public EFCoreDbContext() : base() { } //OnConfiguring() method is used to select and configure the data source protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { //To Display the Generated the Database Script optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information); //Configuring the Connection String optionsBuilder.UseSqlServer(@"Server=LAPTOP-6P5NK25R\SQLSERVER2022DEV;Database=EFCoreDB1;Trusted_Connection=True;TrustServerCertificate=True;"); } //OnModelCreating() method is used to configure the model using ModelBuilder Fluent API protected override void OnModelCreating(ModelBuilder modelBuilder) { //use this to configure the model } //Adding Domain Classes as DbSet Properties public DbSet<Student> Students { get; set; } public DbSet<Standard> Standards { get; set; } } }
Inside the OnConfiguring method, we have added the following statement. The following statement will log the generated SQL Script on the Console window.
optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information);
Create Operation using Entity Framework Core:
Create Operation means we need to add a new object. Adding a new object using Entity Framework Core is very simple. First, you need to create an instance of the Entity which you want to add to the database. Once you created the instance of the entity, then you need to call the Add method of the DbSet or DbContext class and pass the entity. Finally, call the SaveChanges method on the DbContext object, which will insert the new record into the database by generating the INSERT SQL Statement.
Note: The DbSet.Add and DbContext.Add methods add a new entity to a context (instance of DbContext) which will insert a new record in the database when you call the SaveChanges() method.
For a better understanding, modify the Main method of the Program class as follows. In the below example, context.Students.Add(newStudent) adds the newly created student entity to the context object with Added Entity State. EF Core introduced the new DbContext.Add method, which does the same thing as the DbSet.Add method. Most often, we are going to use the DbContext.Add by omitting the type parameter because the compiler will infer the type from the argument passed into the method. Here, I have shown you three different ways to add the student entity to the context object.
using EFCoreCodeFirstDemo.Entities; namespace EFCoreCodeFirstDemo { public class Program { static void Main(string[] args) { try { //Create a new student which you want to add to the database var newStudent = new Student() { FirstName = "Pranaya", LastName = "Rout", DateOfBirth = new DateTime(1988, 02, 29), Height = 5.10m, Weight = 72 }; //Create DBContext object using var context = new EFCoreDbContext(); //Add Student Entity into Context Object //Method1: Add Student Entity Using DbSet.Add Method context.Students.Add(newStudent); //Method2: Add Student Entity Using DbContext.Add Method with Type Parameter //context.Add<Student>(newStudent); //Method2: Add Student Entity Using DbContext.Add Method without Type Parameter //context.Add(newStudent); //Now the Entity State will be in Added State Console.WriteLine($"Before SaveChanges Entity State: {context.Entry(newStudent).State}"); //Call SaveChanges method to save student entity into database context.SaveChanges(); //Now the Entity State will change from Added State to Unchanged State Console.WriteLine($"After SaveChanges Entity State: {context.Entry(newStudent).State}"); Console.WriteLine("Student Saved Successfully..."); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); ; } Console.ReadKey(); } } }
With the above changes in place, run the application and get the following output.
If you verify the SQL Server database, you will see that the above entity is inserted into the Students database table, as shown in the image below.
Update Operation in Entity Framework Core:
As we already discussed in the connected environment, the Entity Framework keeps track of all the entities retrieved using the context object. Therefore, when we edit any entity data, the Entity Framework will automatically mark the Entity State as Modified, and when the SaveChanges method is called, it updates the updated data into the underlying database by generating the UPDATE SQL Statement.
The following code changes the student’s first and last names, whose id is 1. The following example code is self-explained, so please go through the comment lines.
using EFCoreCodeFirstDemo.Entities; namespace EFCoreCodeFirstDemo { public class Program { static void Main(string[] args) { try { //Create DBContext object using var context = new EFCoreDbContext(); //Fetch the Student from database whose Id = 1 var student = context.Students.Find(1); if(student != null) { //At this point Entity State will be Unchanged Console.WriteLine($"Before Updating Entity State: {context.Entry(student).State}"); //Update the first name and last name student.FirstName = "Prateek"; student.LastName = "Sahu"; //At this point Entity State will be Modified Console.WriteLine($"After Updating Entity State: {context.Entry(student).State}"); //Call SaveChanges method to update student data into database context.SaveChanges(); //Now the Entity State will change from Modified State to Unchanged State Console.WriteLine($"After SaveChanges Entity State: {context.Entry(student).State}"); Console.WriteLine("Student Updated Successfully..."); } else { Console.WriteLine("Invalid Student ID : 1"); } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); ; } Console.ReadKey(); } } }
In the above example, first, we retrieve the student from the database using the DbSet Find method, which generates a SELECT SQL query. As soon as we modify the FirstName and LastName, the context object sets its Entity State to Modified, and when we call the SaveChanges() method, it builds and executes the Update SQL statement in the database. Run the above code, and you will get the following output.
Note: The context object in Entity Framework Core keeps track of the columns of an entity that are modified, and based on the modified columns, it will generate the UPDATE SQL statement, and here in the where condition, it is going to use the primary key column. If one column value is not updated, it will not include that column while updating the database. So you can see the update statement. It only includes the First Name and Last Name.
Delete Operation in Entity Framework Core:
We need to use the Remove method of the DbSet object to delete an entity using Entity Framework Core. The DbSet Remove method works for existing and newly added entities tracked by the context object.
Calling the Remove method on an existing entity that is being tracked by the context object will not immediately delete the entity, rather it will mark the entity state as Deleted, and when we call the SaveChanged method, then the Entity is going to be deleted from the database by generating the DELETE SQL Statement, and once the Save Changes method executed successfully, it will mark the entity state as Detached which means now the entity is not going to be tracked by the context object.
In the following example, we are removing a student from the database whose StudentId is 1. The following example code is self-explained, so please go through the comment lines.
using EFCoreCodeFirstDemo.Entities; namespace EFCoreCodeFirstDemo { public class Program { static void Main(string[] args) { try { //Create DBContext object using var context = new EFCoreDbContext(); //Find the Student to be deleted by Id var student = context.Students.Find(1); if (student != null) { //At this point the Entity State will be Unchanged Console.WriteLine($"Entity State Before Removing: {context.Entry(student).State}"); //The following statement mark the Entity State as Deleted context.Students.Remove(student); //context.Remove<Student>(student); //context.Remove(student); //At this point, the Entity State will be in Deleted state Console.WriteLine($"Entity State After Removing: {context.Entry(student).State}"); //SaveChanges method will delete the Entity from the database context.SaveChanges(); //Once the SaveChanges Method executed successfully, //the Entity State will be in Detached state Console.WriteLine($"Entity State After Removing: {context.Entry(student).State}"); } else { Console.WriteLine("Invalid Student ID: 1"); } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); ; } Console.ReadKey(); } } }
In the above example, context.Students.Remove(student) marks the student entity object as Deleted, and when we call the SaveChanges method on the Context object, the Entity Framework will build and execute the DELETE statement in the database, and then it will mark the entity state as Detached, means the context object is no longer tracking it. Run the above code, and you should get the following output.
In the next article, I am going to discuss Entity States in Entity Framework Core. In this article, I try to explain CRUD Operations in Entity Framework Core (EF Core). I hope you enjoy this CRUD Operations in EF Core article.