entity framework6.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 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的post,但在另一个post中,未更改的字段(因此不在附加的模型中)不是强制性的,这就是它起作用的原因。 由于您的字段是必填字段,因此您将收到此validation错误。

您可以通过部分更新的entity frameworkvalidation中提供的解决方案来解决您的问题

validation是导致它不被保存的。 您可以使用context.Configuration.ValidateOnSaveEnabled = false;禁用validationcontext.Configuration.ValidateOnSaveEnabled = false; 它会起作用。 要validation特定字段,可以调用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; } 

(为清晰起见编辑)

上下文必须具有对象的完整副本才能实施业务规则。 只有在附加对象填充了所有必需的属性或者在更新之前将部分视图与完整副本合并时,才会发生这种情况。

我相信你想做的事情在概念上是不可能的:做这样的更新需要保留的更改前副本,或者需要对数据库进行两次查询,因为业务层需要对象的完整副本以进行validation。