static void

Entity Framework Code First Validation

You can turn off validation completely (for instance, if an entity has already been validated).

//default to validate on save
context.Configuration.ValidateOnSaveEnabled = false;

Validation Rules

Use DataAnnotations:

[Required, StringLength(50)]
public string LastName { get; set; }

Or fluent mapping:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        .Property(p => p.LastName).HasMaxLength(50).IsRequired();

Or IValidatableObject (or IDataErrorInfo).

public class Customer : IValidatableObject
    public int Id { get; set; }
    public string FirstName { get; set; }
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        var results = new List<ValidationResult>();
        if (FirstName.Contains("\n"))
                new ValidationResult("Newline character is illegal",
                    new[] { "FirstName" }));
        return results;

Valildate In DbContext

The context has two extension points into validation. ValidateEntity allows custom validation to be added:

protected override DbEntityValidationResult ValidateEntity(
    DbEntityEntry entityEntry,
    IDictionary<object, object> items)
    //do the base DataAnnotations/fluent validation mapping
    var result = base.ValidateEntity(entityEntry, items);
    //do additional validation for customer
    var customer = entityEntry.Entity as Customer;
    //could be added or updated (change ShouldValidateEntity to include deleted)
    if (entityEntry.State == EntityState.Added &&
        customer != null)
        if (customer.FirstName.Contains("\t"))
                new DbValidationError("LastName", "Illegal character"));
    return result;

ShouldValidateEntity is a simple boolean to add/exclude entities for validation.

protected override bool ShouldValidateEntity(
    DbEntityEntry entityEntry)
    if (entityEntry.Entity is Employee)
        return false; //don't validate employees
    if (entityEntry.Entity is Customer && entityEntry.State == EntityState.Deleted)
        return true; //validate deleted customers
    //default: validate all added and updated entities
    return base.ShouldValidateEntity(entityEntry);

Validate OnSave vs On Demand

You can turn on and off validation on save.

//default to validate on save
context.Configuration.ValidateOnSaveEnabled = false;

For OnSave (default) you'll get a DbEntityValidationException:

using (var context = new DomainContext())
        var newEmployee = new Employee { LastName = "Smith" };
    //need a reference to System.Data (System.Data.Entity.Validation)
    catch (DbEntityValidationException entityValidationException)
        foreach (var result in entityValidationException.EntityValidationErrors)
            //the entity
            foreach (var error in result.ValidationErrors)
                Console.WriteLine(error.PropertyName + " " + error.ErrorMessage);

For OnDemand, you can do for all tracked entities (context), a specific entity or a specific property.

//validate all context
var allResults = context.GetValidationErrors();
//validate entity
var result = context.Entry(newEmployee).GetValidationResult();
//validate property
var errors = context.Entry(newEmployee).Property(x => x.LastName)