Entity Framework GetValidationErrors empty for unique index

.net c# entity-framework entity-framework-6 validation

Question

I want to check for validation errors before I save the context. I call context.GetValidationErrors(), which is empty, then I call context.SaveChanges() and I get the error for a duplicate row for my unique index.

using(var context = new DefaultDbContext())
{
    var user = new User()
    {
        OSIdentity = "test"
    };
    var duplicateUser = new User()
    {
        OSIdentity = "test"
    };
    context.Users.Add(user);
    context.Users.Add(duplicateUser);    
    // this is empty
    var errors = context.GetValidationErrors(); 
    if(errors.Count == 0)
    {
        // this throws the exception for duplicate row for unique index "Idx_UserOSIdentity"
        context.SaveChanges();
    }
}

My User Entity has the following column:

[Index("idx_UserOSIdentity", IsUnique = true)]
[Display(Name = "OSIdentity")]
[Required(AllowEmptyStrings = false, ErrorMessage = "...")]
[StringLength(450, ErrorMessage = "...")]
public string OSIdentity { get; set; }

Why is the unique index not checked when context.GetValidationErrors() is called, but is thrown afterwards on context.SaveChanges()?

1
1
3/3/2017 6:12:11 AM

Accepted Answer

This is expected behavior as per EF architecture.

EF has four types of data validations;

Data Annotations: mainly for UI error check like length, email format etc, the IndexAttribute is not a validation attribute, it also doesn't have the ErrorMessage property, and it also doesn't have the IsValid() method that is used to validate it against a range of valid values. This is the reason getValidationErrors is not checking uniqueness.

IValidatableObject: Hook for more custom checks, by adding a 'validate' method to do more complex check than can not be achieved with the data annotations

ValidateEntity: A DbContext method that allows access to the database for doing validation. In My view here you can write you own logic to check the uniqueness before saving.

DbUpdateException: Capturing database-generated errors, EF works on top of our database and database has its own data integrity, after EF’s SaveChanges() or SaveChangesAsync() in case of database integrity failure like your case of uniqueness failure then the commit is rolled back and the errors are passed back via an exception.

This is purely as per your choice, where do you want to catch/handle the database's data integrity exceptions.

2
3/3/2017 6:40:17 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow