Disconnected Entities in Entity Framework Core

Disconnected Entities in Entity Framework Core (EF Core)

In this article, I will discuss Disconnected Entities in Entity Framework Core (EF Core) with Examples. Please read our previous article, discussing Asynchronous Programming with Entity Framework Core with Examples. At the end of this article, you will understand the following pointers:

  1. Type of Entities in Entity Framework Core
  2. What are Disconnected Entities Entity Framework Core?
  3. How to Use Disconnected Entities Entity Framework Core?
  4. How to Save a Disconnected Entity in Entity Framework?
  5. Example to Understand Disconnected Entity in Entity Framework Core
  6. How to Save a New Entity in Entity Framework Core Disconnected Scenario?
  7. How to Update an Existing Entity in Entity Framework Core Disconnected Scenario?
  8. How to Delete a Disconnected Entity in Entity Framework Core?
  9. When to use Disconnected Entity in Entity Framework Core?
Type of Entities in Entity Framework Core:

In Entity Framework Core (EF Core), entities can be in one of three states with respect to tracking:

  • Tracked Entities: These entities are actively tracked by the EF Core context. Any changes to these entities will be detected and persisted in the database when the context is saved.
  • Detached Entities: These entities were previously tracked by the context but have been detached. This can happen when you explicitly detach an entity, when the context is disposed, or when the entity was never tracked by the context in the first place.
  • Disconnected Entities: The context did not track these entities from the beginning. You may create entity objects independently of the context, manipulate them, and then attach them to the context when ready to save changes.
What are Disconnected Entities Entity Framework Core (EF Core)?

The Entity Framework Core DbContext instance automatically tracks the entities returned from the database. The context object also tracks any changes we make to these entities, and when we call the SaveChanges Method on the context object, the changes are updated in the database. This is what we have already discussed so far in our previous articles.

In some scenarios, it is also possible that entities are retrieved from the database using one context object and then updated or saved into the database using a different context object. In this scenario, the second context object, to update the entities in the database, needs to know the entity state of the entities, i.e., whether the entities are Added state or existing entities are in Modified or Deleted state.

Disconnected entities in Entity Framework Core refer to entity instances not currently tracked by any DbContext instance. This scenario is common in Web Applications, Web APIs, and other distributed systems where an entity is retrieved in one request and then modified in a subsequent request. Managing disconnected entities properly is important for ensuring data consistency and integrity.

How to Use Disconnected Entities Entity Framework Core (EF Core)?

Working with disconnected entities is a common scenario when dealing with application data. Here are the typical steps to work with disconnected entities in EF Core:

  • Create the Disconnected Entity: Instantiate an entity object representing the data you want to work with. You can create these entities using their parameterless or any other constructor you define.
  • Modify the Entity: Make changes to the entity’s properties as needed.
  • Attach to Context: When you are ready to save changes to the database, you need to attach the disconnected entity to the EF Core context. You can attach the entity to the context using the Attach, Entry, or Add method.
  • Save Changes: After attaching the entity to the context and specifying the desired state (e.g., Added, Modified, Deleted, or Unchanged), you can call SaveChanges to persist the changes to the database.

This process allows us to work with entity objects outside the context and then bring them back into the context for saving changes. Remember that when attaching entities, you must ensure the primary key values are set correctly to match the database records you intend to update or insert.

How to Save a Disconnected Entity in Entity Framework?

In Entity Framework Core, saving data in the disconnected environment differs from saving data in the connected environment. In a disconnected environment, the context object (an instance of the DbContext class) is not aware of the state of the entities, whether the entities are new or existing. Such entities are called Disconnected Entities. In this case, i.e., in the disconnected scenario, first of all, we need to attach the disconnected entities to the context object with the appropriate Entity State to perform INSERT, UPDATE, or DELETE operations in the database.

In the Entity Framework Core Disconnected Scenario, it is our key responsibility to figure out whether the entity is a new one or an existing entity, and based on this, we need to set the appropriate entity state. The important question that should come to your mind is how we will determine whether the entity is new or existing. For this, we need to check the key property value, i.e., the Primary key value of the entity.

If the key property value is greater than zero (in case of Integer column) or Not Null or Empty (in case of String Column), then it is an existing Entity, and we can set the Entity State as Modified. On the other hand, if the key value is zero (in case of Integer column) or Null or Empty (in case of String Column), then it is a new entity, and we need to set the Entity State as Added.

For a better understanding, please have a look at the below diagram. First, we need to attach the Entity. While attaching the entity to the context object, we need to check the primary key column corresponding property value and if the value is greater than 0 (let us assume it is an integer property). We need to set the Entity State as Modified, and if the value equals zero, then we need to set the Entity State as Added. Then, we need to call the SaveChanges method, which will generate either the INSERT or UPDATE SQL Statement based on the Entity State and execute the SQL Statement in the database.

How to Save a Disconnected Entity in Entity Framework?

Example to Understand Disconnected Entity in Entity Framework Core:

In Entity Framework Core, working in a disconnected scenario means that the operations (like adding, modifying, and deleting entities) are being performed outside the context of the DbContext. Let us understand how to Insert, Update, and Delete Entities in the Entity Framework Core Disconnected scenario. For this, we are going to use the following Student Entity.

namespace EFCoreCodeFirstDemo.Entities
{
    public class Student
    {
        public int StudentId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}

Next, modify the context class as follows:

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace EFCoreCodeFirstDemo.Entities
{
    public class EFCoreDbContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //To Display the Generated SQL Statements
            optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information);

            //Configuring the Connection String
            optionsBuilder.UseSqlServer(@"Server=LAPTOP-6P5NK25R\SQLSERVER2022DEV;Database=EFCoreDB;Trusted_Connection=True;TrustServerCertificate=True;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
        }

        public DbSet<Student> Students { get; set; }
    }
}

With the above changes, open the Package Manager Console and Execute the add-migration and update-database commands as follows. You can give any name to your migration. Here, I am giving EFCoreDBMig1. The name that you are giving it should not be given earlier.

Example to Understand Disconnected Entity in Entity Framework Core

How to Save a New Entity in Entity Framework Core Disconnected Scenario?

Let us see how we can save a new entity in a disconnected scenario. Please modify the Main method of the Program class as shown below. The following is an example of the Entity Framework Disconnected Scenario for adding a new entity. 

using EFCoreCodeFirstDemo.Entities;
using Microsoft.EntityFrameworkCore;
namespace EFCoreCodeFirstDemo
{
    public class Program
    {
        static async Task Main(string[] args)
        {
            try
            {
                //Disconnected entity
                Student student = new Student()
                {
                    FirstName = "Pranaya",
                    LastName = "Rout"
                };

                using var context = new EFCoreDbContext();

                //Setting the Entity State Based on the StudentId Key Property Value
                //If StudentId == 0, Means It is a New Entity, So, Set the Entity State as Added
                //If StudentId > 0, Means It is an Existing Entity, So, Set the Entity State as Modified
                //If StudentId < 0, Invalid ID, so throw an Exception

                if(student.StudentId > 0)
                {
                    //Attaching the Entity to the Context Object with Entity State as Modified
                    context.Entry(student).State = EntityState.Modified;
                }
                else if(student.StudentId == 0)
                {
                    //Attaching the Entity to the Context Object with Entity State as Added
                    context.Entry(student).State = EntityState.Added;
                }
                else
                {
                    throw new Exception("InValid Student ID");
                }

                Console.WriteLine($"Before SaveChanges Entity State: {context.Entry(student).State}");
                //Call SaveChanges to Update the Data in the Database
                context.SaveChanges();
                Console.WriteLine($"After SaveChanges Entity State: {context.Entry(student).State}");

                Console.Read();
            }

            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}"); ;
            }
        }
    }
}

In our example, we have not set the StudentId value while creating the student object, so the default value is 0. Hence, in this example, it will set the Entity State as Added, and when we call the SaveChanges method, it will generate and execute the INSERT SQL Statement in the database. So, when you run the above example code, you will get the following output.

How to Save a New Entity in Entity Framework Core Disconnected Scenario?

How to Update an Existing Entity in Entity Framework Core Disconnected Scenario?

Please modify the Main method of the Program class as shown below. The following is an example of the Entity Framework Core Disconnected Scenario for updating an Existing Entity. In the below example, we set the value of the StudentId property, and hence, it will assign the entity State as the Modified state. And when we run the following application, it generates and executes the UPDATE SQL Statement. Please ensure the StudentId you specified here in the Student entity must exist in the database. Else, you will get an exception.

using EFCoreCodeFirstDemo.Entities;
using Microsoft.EntityFrameworkCore;
namespace EFCoreCodeFirstDemo
{
    public class Program
    {
        static async Task Main(string[] args)
        {
            try
            {
                //Disconnected entity
                Student student = new Student()
                {
                    StudentId = 1, //Make Sure StudentId 1 exists in the Database
                    FirstName = "Pranaya",
                    LastName = "Rout"
                };

                using var context = new EFCoreDbContext();

                //Setting the Entity State Based on the StudentId Key Property Value
                //If StudentId == 0, Means It is a New Entity, So, Set the Entity State as Added
                //If StudentId > 0, Means It is an Existing Entity, So, Set the Entity State as Modified
                //If StudentId < 0, Invalid ID, so throw an Exception

                if(student.StudentId > 0)
                {
                    //Attaching the Entity to the Context Object with Entity State as Modified
                    context.Entry(student).State = EntityState.Modified;
                }
                else if(student.StudentId == 0)
                {
                    //Attaching the Entity to the Context Object with Entity State as Added
                    context.Entry(student).State = EntityState.Added;
                }
                else
                {
                    throw new Exception("InValid Student ID");
                }

                Console.WriteLine($"Before SaveChanges Entity State: {context.Entry(student).State}");
                //Call SaveChanges to Update the Data in the Database
                context.SaveChanges();
                Console.WriteLine($"After SaveChanges Entity State: {context.Entry(student).State}");

                Console.Read();
            }

            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}"); ;
            }
        }
    }
}
Output:

How to Update an Existing Entity in Entity Framework Core Disconnected Scenario?

How to Delete a Disconnected Entity in Entity Framework Core?

Deleting a disconnected Entity in Entity Framework Core is very simple. You need to set its state as Delete using the Entry() method, as shown in the below example. Please make sure the StudentId that you specified here in the Student entity exists in the database, otherwise, you will get an exception.

using EFCoreCodeFirstDemo.Entities;
using Microsoft.EntityFrameworkCore;
namespace EFCoreCodeFirstDemo
{
    public class Program
    {
        static async Task Main(string[] args)
        {
            try
            {
                //Disconnected entity
                Student student = new Student()
                {
                    StudentId = 1 //Make Sure StudentId 1 exists in the Database
                };

                using var context = new EFCoreDbContext();

                //Setting the Entity State as Deleted
                context.Entry(student).State = EntityState.Deleted;

                Console.WriteLine($"Before SaveChanges Entity State: {context.Entry(student).State}");
                //Call SaveChanges to Update the Data in the Database
                context.SaveChanges();
                Console.WriteLine($"After SaveChanges Entity State: {context.Entry(student).State}");

                Console.Read();
            }

            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}"); ;
            }
        }
    }
}

The student instance contains only the StudentId key property in the above example. Deleting an entity using the entity framework only requires the key property. context.Entry(student).State = EntityState.Deleted attaches an entity to the context object and sets its state to Deleted. When we call the SaveChanges method on the context object, it generates and executes the DELETE SQL Statement in the database. So, when you run the above example, you will get the following output.

How to Delete a Disconnected Entity in Entity Framework?

When to use Disconnected Entity in Entity Framework Core (EF Core)?

Disconnected entities in Entity Framework Core are often used in scenarios where the DbContext is not continuously available throughout the life cycle of an entity. Disconnected scenarios are common in applications like Web applications, Web APIs, and other multi-tier architectures. Here are some situations where you might use disconnected entities:

  • Web Applications and APIs: HTTP requests are typically short-lived in Web Applications and APIs. The DbContext is often disposed at the end of each request. In this case, disconnected entities are common as the entities may be passed from the client, modified, and then saved back in a new DbContext instance.
  • Multi-tier Architectures: In a multi-tier architecture where the presentation layer is separated from the data access layer, entities are often passed between layers and may not always be attached to a DbContext.
  • Scalability: Disconnected entities can help in scenarios where scalability is important. Since the context is not kept alive, resources like database connections are released quickly, which can be beneficial in high-load scenarios.
  • Long-Running Processes: For long-running processes or desktop applications where keeping a DbContext open for the duration of the operation might not be feasible, working with disconnected entities becomes necessary.
  • Batch Processing: When working with batch processing that handles a large amount of data, you might work with disconnected entities to manage resources effectively.
Considerations When Working With Disconnected Entities:
  • Tracking Changes: Since the DbContext is not tracking changes to disconnected entities, you must manually manage the entities’ state.
  • Concurrency: Handling concurrency can be more complex in disconnected scenarios as the DbContext might not have the original values of the entity.

In the next article, I will discuss Disconnected Entity Graph in Entity Framework Core with Examples. In this article, I try to explain Disconnected Entities in Entity Framework Core with Examples. I hope you enjoyed this article.

Leave a Reply

Your email address will not be published. Required fields are marked *