Disconnected Entities in Entity Framework

Disconnected Entities in Entity Framework

In this article, I am going to explain 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 Entity Framework and the different methods to attach disconnected entities in EF6 with examples.

Note: 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.

Entity Framework Disconnected Entities:

A DbContext instance automatically tracks entities returned from the database, and any changes made to these entities are detected when SaveChanges is called, and the database is also updated as needed. Sometimes entities are queried using one context instance and then saved using a different instance. In this case, the second context instance needs to know whether the entities are new (should be inserted) or existing (should be updated).

The Entities which are not tracked by the context object (DbContext object) are known as disconnected entities in Entity Framework. In this article, let us understand how to make changes to entities that are not being tracked by the context object.

In most of the single-tier applications (the user interface and database access layers run and host in the same application process), we generally performing 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, the business logic layer, and the database access layers run in the different application process), then most of the database CRUD Operations are performed on disconnected entities that are the entities that are not being tracked by the context object.

Methods to Attach Disconnected Entities in Entity Framework

Saving an entity in the disconnected scenario is different than the connected scenario in Entity Framework. There are two things or two steps that need to be taken care of when we get a disconnected entity graph or even a single disconnected entity.

  1. First, we need to attach the entities with the new context object and make sure the context object aware of these entities.
  2. Second, we need to set an appropriate EntityState to each entity manually. This is because the context object doesn’t know anything about the operations to be 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.

Methods to Attach Disconnected Entities in Entity Framework

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.

  1. DbContext.Entry()
  2. DbSet.Add()
  3. DbSet.Attach()

Let us understand the above three methods in detail one by one with examples.

DbContext.Entry()

The Entry() method of DbContext class returns an instance of System.Data.Entity.Infrastructure.DbEntityEntry object for the given entity providing 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 to the context with the specified state to a parent entity and also sets a different EntityState to other entities i.e. to the child entities. For a better understanding of the Entry method, please have a look at the following example. Here, the Student is the main entity or you can say the Parent entity. Standard, StudentAddress, and Courses are the child entities.

using System;
using System.Collections.Generic;
using System.Data.Entity;
namespace DBFirstApproach
{
    class Program
    {
        static void Main(string[] args)
        {
            var student = new Student()
            {
                //Root entity (empty key)
                FirstName = "Steven",
                LastName = "Smith",
                StandardId = 1,
                Standard = new Standard()   //Child entity (with key value)
                {
                    StandardId = 10,
                    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 = 10 } //Child entity (with key value)
                }                       
            };

            using (var context = new EF_Demo_DBEntities())
            {
                context.Entry(student).State = EntityState.Added;

                foreach (var entity in context.ChangeTracker.Entries())
                {
                    Console.WriteLine($"Entity Name: {entity.Entity.GetType().Name} Entity State: {entity.State}");
                }
            }

            Console.Read();
        }
    }
}

Output:

Disconnected Entities in Entity Framework

In the above example, the Student entity graph includes the Standard, StudentAddress, and Course entities. context.Entry(student).State = EntityState.Added; sets the Added state to the parent entity as well as to all the child entities irrespective of whether a 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.

DbContext.Entry() method

DbSet.Add()

The DbSet.Add() method attaches the entire entity graph to a context and automatically applies the Added state to all entities.

using System;
namespace DBFirstApproach
{
    class Program
    {
        static void Main(string[] args)
        {
            //disconnected 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 = "info@dotnettutorials.net"
            };

            disconnectedStudent.Standard = new Standard()  
            {
                StandardId = 10,
                StandardName = "STD10",
                Description = "STD10 Description"
            };

            using (var context = new EF_Demo_DBEntities())
            {
                context.Students.Add(disconnectedStudent);

                // get DbEntityEntry instance to check the EntityState of specified entity
                var studentEntry = context.Entry(disconnectedStudent);
                var addressEntry = context.Entry(disconnectedStudent.StudentAddress);
                var standardEntry = context.Entry(disconnectedStudent.Standard);

                Console.WriteLine($"Student: {studentEntry.State}");
                Console.WriteLine($"StudentAddress: {addressEntry.State}");
                Console.WriteLine($"Standard: {addressEntry.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).

Then the new Student i.e. disconnectedStudent is added to a context object using the Add method. Once the student is added, the code uses the DbContext.Entry method to get access to the change tracking information that Entity Framework has about the new Student. From this change tracking information, the State property is used to write out the current state of the entity.

When you execute the above program, you will get the following output.

different methods to attach disconnected entities in EF6 with examples

The DbSet.Add() method attaches the entire entity graph to a context with the Added state to each entity. Calling context.Savechanges() will execute the INSERT command for all the entities, which will insert new records in the appropriate database table.

DbSet.Attach() Method

The DbSet.Attach() method attaches an entire entity graph to the new context with the Unchanged entity state.

using System;
namespace DBFirstApproach
{
    class Program
    {
        static void Main(string[] args)
        {
            //disconnected 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 = "info@dotnettutorials.net"
            };

            
            using (var context = new EF_Demo_DBEntities())
            {
                context.Students.Attach(disconnectedStudent);

                // get DbEntityEntry instance to check the EntityState of specified entity
                var studentEntry = context.Entry(disconnectedStudent);
                var addressEntry = context.Entry(disconnectedStudent.StudentAddress);
               

                Console.WriteLine("Student: {0}", studentEntry.State);
                Console.WriteLine("StudentAddress: {0}", addressEntry.State);
            }

            Console.Read();
        }
    }
}

Output:

Entity Framework Disconnected Entities with Examples

In the next article, I am going to discuss How to save Disconnected Entity in Entity Framework. In this article, I try to explain Entity Framework Disconnected Entities and I hope you enjoyed this Entity Framework Disconnected Entities article. Please give your valuable feedback and suggestions about this Disconnected Entities in Entity Framework article.

Leave a Reply

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