使用EF Code-First模型在保存或验证之前执行逻辑

时间:2012-03-23 13:56:00

标签: entity-framework entity-framework-4 entity-framework-4.1 ef-code-first code-first

我已经习惯了EF Code First,花了多年时间使用Ruby ORM,ActiveRecord。 ActiveRecord曾经有各种callbacks,如before_validation和before_save,可以在将对象发送到数据层之前对其进行修改。我想知道在EF Code First对象建模中是否存在等效技术。

我知道如何在实例化时设置对象成员,当然,(设置默认值等等),但有时你需要在对象生命周期的不同时刻进行干预。

要使用一个有点人为的例子,假设我有一个连接作者和播放的连接表,用相应的Authoring对象表示:

public class Authoring
{
  public int ID { get; set; }

  [Required]
  public int Position { get; set; }

  [Required]
  public virtual Play Play { get; set; }

  [Required]
  public virtual Author Author { get; set; }
}

其中Position表示与给定Play相关联的作者的零索引排序。 (你可能只有一个“南太平洋”和两位作者一起玩:一个位置为0的“Rodgers”作者和一个位置为1的“Hammerstein”作者。)

假设我想创建一个方法,在保存创作记录之前,它会检查是否有与之关联的Play的任何现有作者。如果不是,则将Position设置为0.如果是,则会找到与该Play相关联的最高值的Position并增加1。

我会在EF代码第一个模型层中实现这样的逻辑?而且,在其他情况下,如果我想在检查验证错误之前按下代码中的数据怎么办?

基本上,我正在寻找与上面提到的Rails生命周期钩子等效的方法,或者至少要伪造它的方法。 :)

2 个答案:

答案 0 :(得分:3)

您可以实施IValidatableObject。这给你一个钩子:

IEnumerable<ValidationResult> Validate(ValidationContext validationContext)

您可以在那里应用验证逻辑。

SavingChanges上还有ObjectContext个事件(您可以从DbContext获取)。

您可以创建一个自定义IDoStuffOnSave界面并将其应用于需要在保存时执行某些逻辑的实体(没有任何开箱即用的功能)

答案 1 :(得分:3)

你可以覆盖DbContext.SaveChanges,在那里修复并调用base.SaveChanges()。如果这样做,您可能需要在进行修复之前调用DetectChanges。顺便说一句。编程实体框架DbContext书(ISBN 978-1-449-31296-1)第192-194页讨论了同样的问题。是的,这是在验证的背景下......