Wednesday, 14 December 2016

EF Basic 22:Disconnected Entities

Disconnected Entities

Before we see how to perform CRUD operation on disconnected entity graph, let's see how to associate disconnected entity graph with the new context instance.
There are two things we need to do when we get a disconnected entity graph or even a single disconnected entity. First, we need to attach entities with the new context instance and make context aware about these entities. Second, set appropriate EntityStates to these entities manually because the new context instance doesn't know anything about the operations performed on the disconnected entities, so the new context cannot apply the appropriate EntityState.
The following figure illustrates this process.
attach disconnected entity graph
Entity Framework API provides some important methods that attaches disconnected entities to the new context and also set EntityStates to all the entities of an entity graph.

DbSet.Add():

DbSet.Add() method attaches the entire entity graph to the new context and automatically applies Added entity state to all the entities.
Consider the following example code.
    
    //disconnected entity graph
    Student disconnectedStudent = new Student() { StudentName = "New Student" };
    disconnectedStudent.StudentAddress = new StudentAddress() { Address1 = "Address", City = "City1" };

    using (var ctx = new SchoolDBEntities())
    {
        //add disconnected Student entity graph to new context instance - ctx
        ctx.Students.Add(disconnectedStudent);
                
        // get DbEntityEntry instance to check the EntityState of specified entity
        var studentEntry = ctx.Entry(disconnectedStudent);
        var addressEntry = ctx.Entry(disconnectedStudent.StudentAddress);

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

        Console.WriteLine("StudentAddress EntityState: {0}",addressEntry.State);
    }
Output:
Student EntityState: Added 
StudentAddress EntityState: Added
As per the above example code, we add disconnectedStudent entity graph using ctx.Students.Add method. Here, parent entity is Student, so we have added a whole entity graph in Students DbSet. We then get the DbEntityEntry instance for Student and StudentAddress entities to check the state of each entity. As you can see in the output, both entities have Added state.
Thus, use Add method of parent DbSet entity to attach the entire entity graph to the new context instance with Added state to each entity. This will execute insert command for all the entities, which will insert new rows in the appropriate database table.

DbSet.Attach():

DbSet.Attach method attaches a whole entity graph to the new context with Unchanged entity state.
Consider the following example code.
    
    //disconnected entity graph
    Student disconnectedStudent = new Student() { StudentName = "New Student" };
    disconnectedStudent.StudentAddress = new StudentAddress() { Address1 = "Address", City = "City1" };

    using (var ctx = new SchoolDBEntities())
    {
        //attach disconnected Student entity graph to new context instance - ctx
        ctx.Students.Attach(disconnectedStudent);
                
        // get DbEntityEntry instance to check the EntityState of specified entity
        var studentEntry = ctx.Entry(disconnectedStudent);
        var addressEntry = ctx.Entry(disconnectedStudent.StudentAddress);

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

        Console.WriteLine("StudentAddress EntityState: {0}",addressEntry.State);
    }
Output:
Student EntityState: Unchanged 
StudentAddress EntityState: Unchanged
As per the above code, we can attach disconnected entity graph using DbSet.Attach method. This will attach the entire entity graph to the new context with Unchanged entity state to all entities.
Thus, Attach method will only attach entity graph to the context, so we need to find the appropriate entity state for each entity and apply it manually.

DbContext.Entry():

Entry method of DbContext returns DbEntityEntry instance for a specified entity. DbEntityEntry can be used to change the state of an entity.
DbContext.Entry(disconnectedEntity).state = EntityState.Added/Modified/Deleted/Unchanged
This method attaches a whole entity graph to the context with specified state to the parent entity and set the state of other entities, as shown in the following table.
Parent Entity StateEntity State of child entities
AddedAdded
ModifiedUnchanged
DeletedAll child entities will be null

No comments:

Post a Comment