Back to: Entity Framework Tutorials For Begineers and Professionals
Disconnected Entities in Entity Framework with Examples
In this article, I am going to discuss Entity Framework Disconnected Entities with Examples. Please read our previous article, where we discussed Explicit Loading in Entity Framework. At the end of this article, you will understand what are exactly Disconnected Entities in the Entity Framework and the different methods to attach disconnected entities in Entity Framework 6 with examples. We are going to work with the same example that we created in our Introduction to Entity Framework Database First Approach article. Please read our introduction to Entity Framework Database First article before proceeding to this article.
Disconnected Entities Entity Framework:
The Entity Framework DbContext instance automatically tracks the entities which are returned from the database, and any changes that we made to these entities are also tracked by the context object, and when we call the SaveChanges Method on the context object, the changes are updated to the database. This is what we have already discussed so far in this course in our previous articles.
In some scenarios, it is also possible that entities are retrieved from the database using one context object and then going to be updated into the database or saved into the database using a different context object. In this type of scenario, the second context object, in order to update the entities in the database, needs to know the entity state of the entities i.e. whether the entities are new (should be inserted i.e. the state is Added) or existing (should be updated i.e. the state is Modified or Deleted).
Note: The point that you need to remember is that the Entities which are not tracked by the context object (i.e. DbContext instance) are known as Disconnected Entities in Entity Framework.
Now, let us understand how to make changes to entities that are not being tracked by the context object i.e. modifying the Disconnected Entities in Entity Framework.
Methods to Attach Disconnected Entities in Entity Framework
Saving an entity in the disconnected environment is different than the connected environment in Entity Framework. There are two things or two steps that need to be taken care of when we get a disconnected entity graph (Entity Graph means the Main Entity with its related entities) or even a single disconnected Entity i.e. without child entities.
- First, we need to attach the disconnected entities with the new context object and make sure the context object is aware of these entities.
- Second, we need to set an appropriate EntityState for each Disconnected Entity manually. This is because the context object doesn’t know anything about the operations performed on the disconnected entities, so it cannot apply the appropriate EntityState automatically.
For a better understanding of the above-discussed two points, please have a look at the following diagram which illustrates the above two points. Here, you can see, we are having Disconnected Entity Graph i.e. Main Entity with its related child entities. Then we are attaching the Disconnected Entity Graph with the new Context object and then setting the entity state of each entity i.e. Modified, Added, or Unchanged.
The Entity Framework provides the following three methods to attach disconnected entities to a context object and also set the EntityState to each entity in an entity graph.
- DbContext.Entry()
- DbSet.Add()
- DbSet.Attach()
Let us understand the above three methods in detail one by one with examples.
DbContext.Entry() Method to Add Disconnected Entity to Context Object in Entity Framework
The Entry() method of DbContext class returns an instance of System.Data.Entity.Infrastructure.DbEntityEntry object for the given entity provides access to information about the entity and the ability to perform actions on the entity. You can change the EntityState of the specified entity using the State property as shown below.
context.Entry(entity).state = EntityState.Added/Modified/Deleted
The Entry Method of DbContext Class attaches an entire Entity Graph (Parent as well as Child Entities) to the context object with the specified state to the parent entity and also sets different Entity State to related entities i.e. to the child entities. For a better understanding of the DbContext Entry method, please have a look at the following example. Here, the Student Entity is the main entity or you can say the Parent entity. Standard, StudentAddress, and Courses are the Child Entities or related entities, and combined together we can say it’s an Entity Graph. The following example code is self-explained, so please go through the comment lines.
using System; using System.Collections.Generic; using System.Data.Entity; namespace DBFirstApproach { class Program { static void Main(string[] args) { //Creating the Disconnected Entity //Student Entity Graph (Student plus Standard, StudentAddress, and Courses) //Student is the Main Entity //Standard, StudentAddress, and Courses are the Child Entities var student = new Student() { //Root Entity with Empty key FirstName = "Steven", LastName = "Smith", StandardId = 1, Standard = new Standard() //Child Entity with key value { StandardId = 1, StandardName = "STD10", Description = "STD10 Description" }, StudentAddress = new StudentAddress() //Child Entity with empty key { Address1 = "Address Line1", Address2 = "Address Line2" }, Courses = new List<Course>() { new Course(){ CourseName = "AI" }, //Child Entity Empty key new Course(){ CourseId = 1 } //Child Entity with key value } }; //Creating an Instance of the Context class using (var context = new EF_Demo_DBEntities()) { //Attaching the Disconneect Student Entity Graph to the Context Object with Added State context.Entry(student).State = EntityState.Added; //Checking the Entity State of Each Entity of student Entity Graph foreach (var entity in context.ChangeTracker.Entries()) { Console.WriteLine($"Entity Name: {entity.Entity.GetType().Name} Entity State: {entity.State}"); } } //Later I will show you how to Save the Entity Graph in the Database Console.Read(); } } }
Output:
In the above example, the Student Entity Graph includes the related or child Standard, StudentAddress, and Course Entities. The statement context.Entry(student).State = EntityState.Added; set Entity State as Added to the Parent Entity Student as well as to all the child entities (Standard, StudentAddress, and Course) irrespective of whether the child entity contains an empty key value or not. Thus, it is recommended to use the Entry() method carefully. The following table lists the behavior of the Entry() method. When you set the Parent Entity State as Added, the Child Entities are also going to be in Added State. When you set the Parent Entity State as Modified, the Child Entities are also going to be in UnChanged State and if you set the Parent Entity State as Deleted, the Child Entities are also going to be either in Modified or UnChanged State.
DbSet.Add() Method to Add Disconnected Entity to Context Object in Entity Framework
The DbSet.Add() method attaches the entire Entity Graph to a context object and automatically applies the Added state to all entities i.e. Added state to Parent as well as Child Entities. For a better understanding of the DbSet Add method, please have a look at the following example. Here, the Student Entity is the main entity or you can say the Parent entity. Standard, StudentAddress, and Courses are the Child Entities or related entities. The following example code is self-explained, so please go through the comment lines.
using System; using System.Collections.Generic; namespace DBFirstApproach { class Program { static void Main(string[] args) { //Disconnected Student Entity Graph Student disconnectedStudent = new Student() { FirstName = "Steven", LastName = "Smith", StandardId = 1 }; disconnectedStudent.StudentAddress = new StudentAddress() { Address1 = "Address Line1", Address2 = "Address Line2", Mobile = "1234567890", Email = "Steven@dotnettutorials.net" }; disconnectedStudent.Standard = new Standard() { StandardId = 10, StandardName = "STD10", Description = "STD10 Description" }; disconnectedStudent.Courses = new List<Course>() { new Course(){ CourseName = "AI" }, new Course(){ CourseId = 10 } }; using (var context = new EF_Demo_DBEntities()) { //Adding the Disconnected Entity to Context Object context.Students.Add(disconnectedStudent); //To Check the State of Each Entity foreach (var entity in context.ChangeTracker.Entries()) { Console.WriteLine($"Entity Name: {entity.Entity.GetType().Name}, Entity State: {entity.State}"); } } Console.Read(); } } }
In the above example, first, we create a new Student instance (i.e. disconnectedStudent), and then we also add a new StudentAddress and Standard object to the StudentAddress and Standard property of the newly created student instance (disconnectedStudent). We also add two courses to the Courses property of the disconnectedStudent object.
Then the new Student i.e. disconnectedStudent is added to a context object using the Add method. In this case, not only the main Entity but also the Child Entities are going to be in Added State. Here, we are using context.ChangeTracker.Entries() method to check the state of all entities that are tracked by the context object. When you execute the above code, you will get the following output and you can the state of all Entities in Added State.
The DbSet.Add() method in Entity Framework attaches the entire entity graph to the context object with the Added state. In this case, when we call the context.SaveChanges() method, will generate and execute the INSERT command for all the entities, which will insert new records in the appropriate database table.
DbSet.Attach() Method to Add Disconnected Entity to Context Object in Entity Framework
The DbSet.Attach() method attaches the entire Entity Graph to the new context object and automatically applies the Unchanged state to all entities i.e. Unchanged state to Parent as well as Child Entities. For a better understanding of the DbSet Attach method, please have a look at the following example. Here, the Student Entity is the main entity or Parent entity. Standard, StudentAddress, and Courses are the Child Entities of the Student entity. The following example code is self-explained, so please go through the comment lines.
using System; using System.Collections.Generic; namespace DBFirstApproach { class Program { static void Main(string[] args) { //Disconnected Student Entity Graph Student disconnectedStudent = new Student() { FirstName = "Steven", LastName = "Smith", StandardId = 1 }; disconnectedStudent.StudentAddress = new StudentAddress() { Address1 = "Address Line1", Address2 = "Address Line2", Mobile = "1234567890", Email = "Steven@dotnettutorials.net" }; disconnectedStudent.Standard = new Standard() { StandardId = 1, StandardName = "STD1", Description = "STD1 Description" }; disconnectedStudent.Courses = new List<Course>() { new Course(){ CourseName = "AI" }, new Course(){ CourseId = 10 } }; using (var context = new EF_Demo_DBEntities()) { //Attaching the Disconnected Entity to Context Object context.Students.Attach(disconnectedStudent); //To Check the State of Each Entities foreach (var entity in context.ChangeTracker.Entries()) { Console.WriteLine($"Entity Name: {entity.Entity.GetType().Name}, Entity State: {entity.State}"); } } Console.Read(); } } }
In the above example, first, we create a new Student object (i.e. disconnectedStudent), and then we also add new StudentAddress, Standard, and Courses objects to the StudentAddress, Standard, and Courses property of the disconnectedStudent object.
Then the new student entity graph is attached to the context object using the Attach method. In this case, not only the main Entity but also the Child Entities are going to be in Unchanged State. Here also we are using context.ChangeTracker.Entries() method to check the state of all entities. When you run the above program, you will get the following output and you can the state of all Entities in Unchanged State.
When we use Disconnected Entities in Entity Framework?
In most of the Single-Tier Applications (The User Interface Layer and Data Access Layer, both host and runs on the same server), we generally perform the database CRUD operations on the entities that are being tracked by the context object.
But if you are developing an N-Tier application (the User Interface Layer, the Business Logic Layer, and the Data Access Layer host and runs on different servers), then most of the database CRUD Operations are performed on Disconnected entities which means performing the CRUD Operations on the entities which are not being tracked by the context object.
In the next article, I am going to discuss How to save Disconnected Entity in the Entity Framework. In this article, I try to explain Entity Framework Disconnected Entities with Examples and I hope you enjoyed this Entity Framework Disconnected Entities with Examples article. Please give your valuable feedback and suggestions about this article.