我已经习惯了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生命周期钩子等效的方法,或者至少要伪造它的方法。 :)
答案 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页讨论了同样的问题。是的,这是在验证的背景下......