I have a view model that encapsulates only some of the database model properties. These properties contained by the view model are the only properties I want to update
You based your work on the post https://stackoverflow.com/a/15339512/2015959, but in the other thread the fields that weren't changed (and as such weren't in the attached model) weren't mandatory, and that's why it worked. Since your fields are required, you'll get this validation error.
Your problem can be solved by the solution provided in question Entity Framework validation with partial updates
It is the validation that is causing it not to be saved. You can disable validation with context.Configuration.ValidateOnSaveEnabled = false;
and it will work. To validate specific fields you can call var error = entry.Property(e => e.Name).GetValidationErrors();
. So you certainly can make an 'UpdateNameAndAge' method that only only enforces business rules and flags those properties as modified. No double query required.
private static bool UpdateNameAndAge(int id, string name, int age)
{
bool success = false;
var context = new PersonContext();
context.Configuration.ValidateOnSaveEnabled = false;
var person = new Person() {Id = id, Name = name, Age = age};
context.Persons.Attach(person);
var entry = context.Entry(person);
// validate the two fields
var errorsName = entry.Property(e => e.Name).GetValidationErrors();
var errorsAge = entry.Property(e => e.Age).GetValidationErrors();
// save if validation was good
if (!errorsName.Any() && !errorsAge.Any())
{
entry.Property(e => e.Name).IsModified = true;
entry.Property(e => e.Age).IsModified = true;
if (context.SaveChanges() > 0)
{
success = true;
}
}
return success;
}
(Edited for clarity)
The context must have a complete copy of the object to enforce business rules. This can only happen if the attached object has all the necessary properties populated or the partial view is merged with a complete copy before updating.
I believe that what you want to do is conceptually impossible: doing updates like this will require either a preserved pre-change copy, or two queries to the database because the business layer needs a full copy of the object for validation.