【发布时间】:2012-10-04 00:37:37
【问题描述】:
我正在使用带有 DbContext 和 POCO 实体的 Entity Framework 5.0。有一个包含 3 个属性的简单实体:
public class Record
{
public int Id { get; set; }
public string Title { get; set; }
public bool IsActive { get; set; }
}
Title 字段始终未修改,UI 只是显示它,而不提供任何输入框来修改它。这就是为什么在将表单发送到服务器时将Title 字段设置为null。
这是我告诉 EF 执行实体的部分更新的方法(仅限IsActive 字段):
public class EFRepository<TEntity>
{
...
public void PartialUpdate(TEntity entity, params Expression<Func<TEntity, object>>[] propsToUpdate)
{
dbSet.Attach(entity);
var entry = _dbContext.Entry(entity);
foreach(var prop in propsToUpdate)
contextEntry.Property(prop).IsModified = true;
}
}
和电话:
repository.PartialUpdate(updatedRecord, r => r.IsActive);
调用SaveChanges 方法,我得到DbEntityValidationException,它告诉我,Title 是必需的。当我设置dbContext.Configuration.ValidateOnSaveEnabled = false 时,一切正常。
有什么方法可以避免禁用整个上下文的验证并告诉 EF 不要验证未更新的属性?
提前致谢。
【问题讨论】:
-
这似乎需要做很多工作,否则很容易处理。您只需在表单中包含一个包含只读模型项的隐藏字段,然后它们会包含在更新中,EF 会进行更改跟踪并知道值没有更改。
-
存根实体比呢?例如,我有一个将实体标记为已删除的 Action 方法。以下代码:
var person = new Person { Id = 5 }; dbSet.Attach(person); dbSet.Entry(person).Property(p => p.IsDeleted).IsModified = true; dbContext.SaveChanges();将导致相同的异常。 DbContext 验证是否完全适用于存根实体?我想避免从数据库中检索整个实体只是为了将其标记为已删除。 -
真的有用吗?当您手头有一个实体并且您确定该实体存在于数据库中并且是相同的时,使用附加。您附加的实体与商店中的不同(标题不同)。然后将实体标记为已修改(通过标记要修改的属性)。由于 EF 对实体而不是属性进行操作,因此它将更新所有属性,而不仅仅是标记为已修改的属性。我的 EF 心智模型告诉我,在此之后数据库中的 Title 列将设置为 null。你能检查一下是不是这样吗?
-
默认情况下验证会验证处于已添加和已修改状态的实体的所有属性。可以通过使用验证公开的扩展机制来更改此行为。请注意,一旦您将附加的实体标记为已修改,它就不再是存根实体,因为我相信它将被发送到数据库......
-
EF 允许对实体进行部分更新。例如,
dbSet.Attach(entity); dbContext.Entry(entity).State = EntityState.Modified; dbContext.SaveChanges();将更新整个实体。如果您明确告诉 EF,要更新哪些属性,则只会更新这些属性。dbSet.Attach(entity); dbContext.Entry(entity).Property(e => e.Title).IsModified = true; dbContext.SaveChanges();将仅更新标题。禁用验证后,这很有效。
标签: entity-framework validation updates