Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework 6.1 Updating a Subset of a Record

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. I want the other properties to preserve their value.

During my research I found this answer which appears to be perfect for my needs however, despite my best efforts, I cannot get the code to work as expected.

Here is an isolated example of what I came up with:

static void Main() {
    // Person with ID 1 already exists in database.

    // 1. Update the Age and Name.
    Person person = new Person();
    person.Id = 1;
    person.Age = 18;
    person.Name = "Alex";

    // 2. Do not update the NI. I want to preserve that value.
    // person.NINumber = "123456";

    Update(person);
}

static void Update(Person updatedPerson) {
    var context = new PersonContext();

    context.Persons.Attach(updatedPerson);
    var entry = context.Entry(updatedPerson);

    entry.Property(e => e.Name).IsModified = true;
    entry.Property(e => e.Age).IsModified = true;

    // Boom! Throws a validation exception saying that the 
    // NI field is required.
    context.SaveChanges();
}

public class PersonContext : DbContext {
    public DbSet<Person> Persons { get; set; }
}

public class Person {
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    [Required] 
    public int Age { get; set; } // this is contrived so, yeah.
    [Required]
    public string NINumber { get; set; }
}

What am I doing wrong?

like image 715
Caster Troy Avatar asked May 09 '14 14:05

Caster Troy


2 Answers

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

like image 110
Radu Pascal Avatar answered Nov 16 '22 22:11

Radu Pascal


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;
  }
like image 32
jltrem Avatar answered Nov 16 '22 20:11

jltrem