I’m experiencing a problem in breaking a relationship bteween two entities. Let’s say we have a Child entity which belongs to one Parent, a Parent has many Child entities. Now in my front end a user can select a radio button to choose which Parent the Child belongs to or they can choose “None”. The trouble I’m having is that when I edit a Child record and select “None”, it doesn’t seem to break an existing relationship.
In my business logic I am doing the following:
child.Parent = parentRepository.Find(command.ParentID);
The repository method returns null if no record matches the passed in ID, and selecting “None” gives an ID of 0 yet when I debug and step over this line, Child.Parent still has a reference to the previously chosen Parent entity. In fact, even explicitly setting Child.Parent = null; doesn’t seem to break the link.
To add to my confusion, this isn’t consistant behaviour. Every now and then the same code does break the relationship and set Child.Parent to null! Can someone please point me in the right direction?
UPDATE
I updated my code to ensure that the repo is returning null.
Parent parent = parentRepository.Find(command.ParentID);
if (parent == null)
child.parent = null;
else
child.parent = parent;
Debugging shows that the line child.parent = null; is being executed, yet when I check child.parent after this line, it still shows a reference to the previously referenced Parent object. But every now and then, it is correctly setting to null. This version works:
Parent parent = parentRepository.Find(command.ParentID);
if (parent == null)
{
child.parent = null;
child.parent = null;
}
else
child.parent = parent;
Why do I have to set it to null twice to get consistant behaviour? Do I have to explicitly declare that Parent is nullable on the Child entity somehow?
Yes, you do need to declare that the parent is nullable.
If you expose a foreign key property on the child, it has to be nullable. So if your child has a ParentId property, it should look like this:
If you are using the fluent API, you can tell EF that the parent is nullable like this:
Or like this, if you declare the relationship from the principal end rather than the dependent end:
It is strange that the child.Parent needs to be set to null twice. Have you tried stepping into the code to see why? You could also try this for your Parent property, to see exactly what is going on:
This is code you can actually step into, to make sure that the private field is being set to null.
Response to comment
It does sound like there is an issue with lazy loading going on. Try this.
In your repository Find method, eager load the parent. You can do that with something like this:
This would make child.Parent already loaded on the context, and setting to null once should suffice.