Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Executing logic before save or validation with EF Code-First Models

I'm still getting accustomed to EF Code First, having spent years working with the Ruby ORM, ActiveRecord. ActiveRecord used to have all sorts of callbacks like before_validation and before_save, where it was possible to modify the object before it would be sent off to the data layer. I am wondering if there is an equivalent technique in EF Code First object modeling.

I know how to set object members at the time of instantiation, of course, (to set default values and so forth) but sometimes you need to intervene at different moments in the object lifecycle.

To use a slightly contrived example, say I have a join table linking Authors and Plays, represented with a corresponding Authoring object:

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

where Position represents a zero-indexed ordering of the Authors associated to a given Play. (You might have a single "South Pacific" Play with two authors: a "Rodgers" author with a Position 0 and a "Hammerstein" author with a Position 1.)

Let's say I wanted to create a method that, before saving away an Authoring record, it checked to see if there were any existing authors for the Play to which it was associated. If no, it set the Position to 0. If yes, it would find set the Position of the highest value associated with that Play and increment by one.

Where would I implement such logic within an EF code first model layer? And, in other cases, what if I wanted to massage data in code before it is checked for validation errors?

Basically, I'm looking for an equivalent to the Rails lifecycle hooks mentioned above, or some way to fake it at least. :)

like image 762
Ryan Norbauer Avatar asked May 25 '26 05:05

Ryan Norbauer


2 Answers

You can override DbContext.SaveChanges, do the fix up there and call into base.SaveChanges(). If you do that you may want to call DetectChanges before doing the fix up. Btw. the very same issue is discussed in Programming Entity Framework DbContext book (ISBN 978-1-449-31296-1) on pages 192-194. And yes, this is in context of validation...

like image 163
Pawel Avatar answered May 27 '26 20:05

Pawel


You can implement IValidatableObject. That gives you a single hook:

IEnumerable<ValidationResult> Validate(ValidationContext validationContext)

And you can apply your validation logic there.

There's also a SavingChanges event on ObjectContext (which you can obtain from the DbContext).

You could just create a custom IDoStuffOnSave interface and apply it to your entities that need to execute some logic on save (there's nothing out of the box)

like image 43
Diego Mijelshon Avatar answered May 27 '26 20:05

Diego Mijelshon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!