In this chapter, let us look at how to make changes to entities that are not being tracked by a context. Entities that are not being tracked by a context are known as ‘disconnected’ entities.
For most single-tier applications, where the user interface and database access layers run in the same application process, you will probably just be performing operations on entities that are being tracked by a context.
Operations on disconnected entities are much more common in N-Tier applications.
N-Tier applications involve fetching some data on a server and returning it, over the network, to a client machine.
The client application then manipulates this data before returning it to the server to be persisted.
Following are the two steps that needs to be taken with disconnected entity graph or even a single disconnected entity.
Attach entities with the new context instance and make context aware about these entities.
Set appropriate EntityStates to these entities manually.
Let’s take a look at the following code in which Student entity is added with two Enrollment entities.
class Program { static void Main(string[] args) { var student = new Student { ID = 1001, FirstMidName = "Wasim", LastName = "Akram", EnrollmentDate = DateTime.Parse("2015-10-10"), Enrollments = new List<Enrollment> { new Enrollment{EnrollmentID = 2001,CourseID = 4022, StudentID = 1001 }, new Enrollment{EnrollmentID = 2002,CourseID = 4025, StudentID = 1001 }, } }; using (var context = new UniContextEntities()) { context.Students.Add(student); Console.WriteLine("New Student ({0} {1}): {2}", student.FirstMidName, student.LastName, context.Entry(student).State); foreach (var enrollment in student.Enrollments) { Console.WriteLine("Enrollment ID: {0} State: {1}", enrollment.EnrollmentID, context.Entry(enrollment).State); } Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } } }
The code constructs a new Student instance, which also references two new Enrollment instances in its Enrollments property.
Then the new Student is added to a context 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.
This process is then repeated for each of the newly created Enrollments that are referenced from the new Student. If you run the application, you will receive the following output −
New Student (Wasim Akram): Added Enrollment ID: 2001 State: Added Enrollment ID: 2002 State: Added Press any key to exit...
While DbSet.Add is used to tell Entity Framework about new entities, DbSet.Attach is used to tell Entity Framework about existing entities. The Attach method will mark an entity in the Unchanged state.
Let’s take a look at the following C# code in which a disconnected entity is attached with DbContext.
class Program { static void Main(string[] args) { var student = new Student { ID = 1001, FirstMidName = "Wasim", LastName = "Akram", EnrollmentDate = DateTime.Parse("2015-10-10"), Enrollments = new List<Enrollment> { new Enrollment { EnrollmentID = 2001, CourseID = 4022, StudentID = 1001 }, new Enrollment { EnrollmentID = 2002, CourseID = 4025, StudentID = 1001 }, } }; using (var context = new UniContextEntities()) { context.Students.Attach(student); Console.WriteLine("New Student ({0} {1}): {2}", student.FirstMidName, student.LastName, context.Entry(student).State); foreach (var enrollment in student.Enrollments) { Console.WriteLine("Enrollment ID: {0} State: {1}", enrollment.EnrollmentID, context.Entry(enrollment).State); } Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } } }
When the above code is executed with Attach() method, you will receive the following output.
New Student (Wasim Akram): Unchanged Enrollment ID: 2001 State: Unchanged Enrollment ID: 2002 State: Unchanged Press any key to exit...