0

I know it is possible to manually add attributes to entity properties, but can the entity framework generate this for me? For example, it knows the maximum length is 6 (if you look at the properties in the entity designer).

What happens now is that I get a nasty generic error message with no indication of the field's length.

I suppose I need training in Entity Framework for MVC which I should squeeze in somewhere between deadlines. :-)

Community
  • 1
  • 1
Peet Brits
  • 2,911
  • 1
  • 31
  • 47

2 Answers2

1

You could probably achieve this by creating your own T4 templates.

However, validation is something I won't do in your data layer alone, but especially in your business layer. After all, it's not only the maximum length of a field that is important, but also whether it's mandatory or not, a number within specific ranges, validations that are dependent on other entities, and so on. Not every validation/business rule can be auto-generated, as it mostly also depends on context. Depending on your architecture you can for example don't allow the creation of an object if requirements are not fulfilled.

A nice framework for doing this kind of validation is FluentValidation. It allows you to isolate the validations in separate classes; and even reuse them.

Your data layer could be responsible for data validation like checking foreign key or other constraints.

L-Four
  • 13,345
  • 9
  • 65
  • 109
  • If the restrictions are based on persistence layer restrictions, then it should absolutely be in the data-access layer (which should be above the data layer). – krillgar Jun 11 '14 at 14:55
  • I will google T4 templates and see if it can help me. What I want is for Entity Framework validation to display (as part of e.g. `ModelState.IsValid`) without having to manually handle the exception in all my generated controllers. – Peet Brits Jun 13 '14 at 13:18
1

Ways to create:

  • Database first
    • existing database -> generated data model
  • Model first :
    • data model -> generated database
  • Code first :
    • existing database -> generated data model
    • data model -> generated database

In case of "Database first" this should be constraint. Checks happen in database.

CREATE TABLE suppliers
(
  supplier_id numeric(4),
  supplier_name varchar2(50),
  CONSTRAINT check_supplier_id
  CHECK (supplier_id BETWEEN 100 and 9999)
);

Example : source

In case of model first you do this with annotations or validation classes. Example Fluent valitation

public class CustomerValidator: AbstractValidator<Customer> {
  public CustomerValidator() {
    RuleFor(customer => customer.Surname).NotEmpty();
    RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
    RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
    RuleFor(customer => customer.Address).Length(20, 250);
    RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
  }

  private bool BeAValidPostcode(string postcode) {
    // custom postcode validating logic goes here
  }
}

Example : source

In case of code first you can add property constraints:

  protected override void OnModelCreating(DbModelBuilder modelBuilder) 
  { 
      modelBuilder.Entity<Blog>().Property(p => p.BloggerName).HasMaxLength(10); 
  } 

Example : source

Margus
  • 19,694
  • 14
  • 55
  • 103
  • Thanks for the detailed response! I think my misunderstanding was that the Entity Framework validation does not happen as part of `ModelState.IsValid`, as is the case for custom data annotations. I have to catch the exception, or use `db.GetValidationErrors()`, and manually call `ModelState.AddModelError` for each validation error. I want to know if there is a way to skip this seemingly needless step for all my generated views. – Peet Brits Jun 13 '14 at 12:43
  • PS: The most instructive part of the answers was the third example source on Entity Framework Validation. (I use database first.) – Peet Brits Jun 17 '14 at 06:51