Entity Framework 6.1 обновление подмножества записи

У меня есть модель представления, которая инкапсулирует только некоторые свойств модели базы данных. Эти свойства, содержащиеся в модели представления, являются единственными свойствами, которые я хочу обновить. Я хочу, чтобы другие свойства сохранили свою ценность.

во время моего исследования я нашел этой ответ, который кажется идеальным для моих нужд, однако, несмотря на все мои усилия, я не могу получить код, чтобы работать, как ожидалось.

вот единичный пример того, что я придумал:

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; }
}

что я делаю не так?

3 ответов


вы основывали свою работу на пост https://stackoverflow.com/a/15339512/2015959, но в другом потоке поля, которые не были изменены (и как таковые не были в прикрепленной модели), не были обязательными, и поэтому это сработало. Поскольку ваши поля необходимы, вы получите эту ошибку проверки.

ваша проблема может быть решена решением, предоставленным в вопросе проверка Entity Framework с частичными обновлениями


это проверка, которая заставляет его не быть сохраненным. Вы можете отключить проверку с помощью context.Configuration.ValidateOnSaveEnabled = false; и оно будет работать. Для проверки определенных полей можно вызвать var error = entry.Property(e => e.Name).GetValidationErrors();. Таким образом, вы можете создать метод UpdateNameAndAge, который только применяет бизнес-правила и помечает эти свойства как измененные. Двойной запрос не требуется.

  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;
  }

(отредактированы для ясности)

контекст должен иметь полную копию объекта для выполнения бизнес-правил. Это может произойти только в том случае, если вложенный объект имеет все необходимые свойства или частичное представление объединяется с полной копией перед обновлением.

Я считаю, что то, что вы хотите сделать, концептуально невозможно: для таких обновлений потребуется либо сохраненная копия перед изменением, либо два запроса к базе данных, потому что бизнес-уровень нуждается полная копия объекта для проверки.