簡體   English   中英

實體框架6.1更新記錄的子集

[英]Entity Framework 6.1 Updating a Subset of a Record

我有一個視圖模型,只封裝了一些數據庫模型屬性。 視圖模型包含的這些屬性是我想要更新的唯一屬性。 我希望其他屬性保留其價值。

在我的研究過程中,我發現這個答案看起來很適合我的需求,但是,盡管我付出了最大的努力,但我無法讓代碼按預期工作。

這是我想出的一個孤立的例子:

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

我究竟做錯了什么?

您的工作基於https://stackoverflow.com/a/15339512/2015959的帖子,但在另一個帖子中,未更改的字段(因此不在附加的模型中)不是強制性的,這就是它起作用的原因。 由於您的字段是必填字段,因此您將收到此驗證錯誤。

您可以通過部分更新的實體框架驗證中提供的解決方案來解決您的問題

正是驗證導致它不被保存。 您可以使用context.Configuration.ValidateOnSaveEnabled = false;禁用驗證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;
  }

(為清晰起見編輯)

上下文必須具有對象的完整副本才能實施業務規則。 只有在附加對象填充了所有必需的屬性或者在更新之前將部分視圖與完整副本合並時,才會發生這種情況。

我相信你想做的事情在概念上是不可能的:做這樣的更新需要保留的更改前副本,或者需要對數據庫進行兩次查詢,因為業務層需要對象的完整副本以進行驗證。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM