Entity Framework Pitfalls: Validation Does Not Load Lazy Properties
In a nutshell: Entity Framework Code First (EFCF) validation does not load lazy properties. If any of these properties is marked as required, and it is not loaded, a validation error will occur.
While I understand the reason – imagine you are saving lots of entities where a required property is not loaded, this will cause lots of accesses to the database just for checking that the required entity exists – I think the way things are is not very productive. I hope the Entity Framework team can come up with a solution, I’ll probably propose something myself.
Imagine you have a class model such as:
1: public class Parent
2: {
3: public Int32 ParentId { get; set; }
4: public virtual ICollection<Child> Children { get; set; }
5: }
6:
7: public class Child
8: {
9: public Int32 ChildId { get; set; }
10: [Required]
11: public virtual Parent Parent { get; set; }
12: }
Say you load a child and make some change:
1: Child c = ctx.Children.Find(1);
2: c.SomeProperty = "...";
3:
4: ctx.SaveChanges();
This will throw a DbEntityValidationException, because EFCF will think that the Child instance does not have its Parent property set. This is really annoying and is the source of great frustration.
Of course, there are some workarounds:
- Explicitly force loading all lazy loaded properties before calling SaveChanges;
1: var p = c.Parent;
- Include all lazy loaded properties in the query (best option), such as:
1: var c = ctx.Children.Where(x => x.ChildId == 1).Include(x => x.Parent).Single();
- Disable validation at all (not recommended):
1: ctx.Configuration.ValidateOnSaveEnabled = false;
- Disable lazy loading globally (also not recommended):
1: ctx.Configuration.LazyLoadingEnabled = false;
2: ctx.Configuration.ProxyCreationEnabled = false;
- Finally, you can remove the required constraint (not good as well):
1: public virtual Parent Parent { get; set; }