Triynko
Triynko

Reputation: 19204

How to partially update a navigation property in EF 6?

Suppose I have a simple entity with children:

public class Entity
{
    public Guid ID { get; set; }
    public ICollection<Child> Children { get; set; }
}

public class Child
{
    public Guid ID { get; set; }
    public Guid ParentEntityID { get; set; }
}

The "Children" property is configured as a one to many relationship. There a few scenarios below that I need clarification on what will happen.

Scenario 1: Assume I load the entity but don't "Include" the Children property:

Scenario 2: Assume I load the entity and also "Include" the Children property:

Scenario 3: Assume I have thousands of Children and want to add or remove just a few of them:

Upvotes: 3

Views: 1089

Answers (1)

Triynko
Triynko

Reputation: 19204

Scenario 1: Assume I load the entity but don't "Include" the Children property: If I then initialize the collection to an empty list and save it... will that wipe out the children or do nothing?

It will do nothing. No children are loaded, so none of their states are tracked. EF doesn't actually care about the collection itself, only the things inside it. You can even reassign a new collection instance, and as long as all the entities are added back into it, you're fine. You can even remove entities from the collection if you Detach them, and they won't be affected in the database. If you detach them all, you can set the collection to null or an empty collection, and it will still save changes without any error. It must perform some kind of closed-loop check on the children... seeing that their ParentID is X, it must then check Parent X to see if that child is still in it's Children collection and throw an error if it's not. It seem to analyze it all as a complete graph of the tracked entities and updates collections automatically when things are loaded. This allowed me to make a prediction that if I loaded a Parent and one of it's children separately and the Parent's Children collection is null, that should cause an error. Indeed, when I load parent by itself, the collection is initially null, and then when I load one or two children separtely, the parent's Children collection is automatically initialized/updated by EF to include the loaded children, such that clearing it would cause the foreign key error.

Scenario 2: Assume I load the entity and also "Include" the Children property: If I clear the collection and save the entity, would that wipe out the children?

Yes. The Include call would load all children into the tracker. It will ensure they're all in the Parent's Children collection, whether you initialized it earlier or not. The "Include" call doesn't really make it function any differnetly, it just causes all the children to enter the change tracker. Loading all the children separately after loading the parent ends up putting the entire system in the same state as if you had just called include up front.

Scenario 3: Assume I have thousands of Children and want to add or remove just a few of them: Do I have to "Include" (i.e. preload) the entire collection in order to add or remove items? If so, how can I perform a partial update of the set without preloading all the children?

Absolutely not. You can load just the ones you want to remove, then remove them from the DbSet. If you don't want to load them up front, you could issue a direct SQL delete statement on the IDs. If you don't call include and don't load any children, then you can just add a few new ones to the collection navigation property and only those few will be added; everything else that's not in the change tracker is left alone.

Upvotes: 1

Related Questions