0

I'm getting a DbEntityValidationException from a controller method that's trying to set the boolean IsVisible on an entity it retrieves from the DB. It's responding to an AJAX post from a change in a tick box on the page. This code used to work.

var targetClass = db.Classes.FirstOrDefault(x => x.ID == cid);
targetClass.IsVisible = true;
db.SaveChanges();

This results in DbEntityValidationException with the following errors:

The SchoolYear field is required.
The TuitionPlan field is required.

When I step through this code both targetClass.SchoolYear and targetClass.TuitionPlan are valid.

Question is, how do I figure out why EF thinks these fields are missing?

EDIT: This may have to do with (too) lazy loading... If I use both of the "missing" fields, the error goes away. Probably nothing more worrisome than not knowing why a serious problem just went away.

var targetClass = db.Classes.FirstOrDefault(x => x.ID == cid);
targetClass.IsVisible = value;
int x = targetClass.TuitionPlan.ID;
x = targetClass.SchoolYear.ID;
db.SaveChanges();

I really need someone to explain what's going on here, and how I should prevent this in the future.

Thanks for insight, Eric

Eric Nelson
  • 763
  • 1
  • 8
  • 17

1 Answers1

0

I don't think it is a good idea to validate navigation properties against null. A navigation property set to null means that there is not a related entity (the condition you want to validate) but can also mean that the relate entity was just not loaded. Now, sending an additional query to the database just to validate it is there seems to be an overkill and may cause performance problems (first and foremost you may be sending a lot of queries to database, second (unless you load the entities as not being tracked) you start tracking many more entities that you actually need track). Also note that for the above reasons validation disables lazy loading until validation is complete. This is probably the reason you see the errors even though in your app lazy loading is enabled. During validation it will be disabled and accessing the navigation property will not load the related entity. If you want to validate whether a related entity exists you can use foreign keys. Note that it won't require loading the related entity and should be relatively easy to do.

Pawel
  • 31,342
  • 4
  • 73
  • 104
  • In short, I should _not_ use the [Required] annotation on navigation properties. Is that correct? – Eric Nelson Nov 11 '12 at 22:49
  • Correct.I would not recommend doing this. – Pawel Nov 11 '12 at 22:52
  • In absence of `[Required]` how do I get delete to cascade? – Eric Nelson Nov 11 '12 at 23:37
  • You can use fluent API to configure this in OnModelCreating. Take a look at this thread: http://stackoverflow.com/questions/5825799/cascade-delete-rule-in-ef-4-1-code-first-when-using-shared-primary-key-associati – Pawel Nov 11 '12 at 23:51