Entity Framework Disconnected Graph and the root
Posted on: 2014-07-23
Entity Framework works with entities that can be attached or not. Attached entities are tracked by Entity Framework. This way, Entity Framework can detect if a change has been made or if something has been deleted. Having an entity not loaded from Entity that exist inside the database is called a disconnect entity. When persisting object into Entity Framework, we are working with graph. This mean that an entity has other reference to entities which can also have other entities. The entity that we are performing an operation on is the root of the graph. Depending of the situation, the root can change. For example, you can have E1 referencing E2 which reference E3. If you are using E2 to do some operation, the root is E2. It is important to understand what is the root because operation executed on the root can have side effect on the rest of the graph.
A simple example is this one. You have an entity that has a list of another type of entities. If you instantiate this entity and add to its list some entities and only do a Context.Add to the root, all entities from the added entity will be also added.
using (var context = new YourContext()) { var newHouse = new House {Address = new Address{City="TestCity",Number = 123,Street="Street Name here"}}; newHouse.Owner = new Person {Name = "Automatically added from the property", BirthDate = DateTime.Now}; newHouse.Resident = new Collection<Person>(new []{new Person{BirthDate = DateTime.Now,Name = "Automatically added from the collection"}}); context.Houses.Add(newHouse); context.SaveChanges(); }
In this example, all Person entity does not exist in the database. The House entity does not exist. Rather to add the House entity and all Person, we just need to add the root element: the House. This is what the code is doing. This execution produces three entries into the database : one for the House, one for the Owner (a Person) and a last one for the Resisdent (a Person).
It is important to notice that Entity Framework is enough bright to no mark a children as "Added" if this one is already been tracked by its context. For example, you load from the database a Person entity and add it to the collection. This one will not be added but will be attached.