Austin_Anderson
Austin_Anderson

Reputation: 940

entity framework core exception handling db first

Background
With ef core code first approach, validation is robust and simple: https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/validation

With the database first approach, it seems like any validation is happening behind the scenes by the database when dbcontext.SaveChanges(); is called. What's worse, these exceptions are nebulous and entirely unhelpful, for example, SqlException: String or binary data would be truncated can be thrown if any of the string properties of any of the entities have too many chars (ours is a legacy app riddled with char(10) and such), or even if a key that is a string is left null.

Question
I want to know if there is any reasonable or accepted way of enforcing the validation. I've found this question which might help debugging, but I would like to enforce the constraints in code

Is there any better method than changing every auto property to one that throws if it's constraints aren't met?

Upvotes: 0

Views: 1146

Answers (2)

Austin_Anderson
Austin_Anderson

Reputation: 940

I ended up going with a psuedo extension to the generator tooling. Since the DBContext is a partial class, I made a new class that has a main

public partial class DBContext{
    public static void Main(string[]args){
        DBContext context = new DBContext();
        var modelbuilder = new Microsoft.EntityFrameworkCore.ModelBuilder(new Microsoft.EntityFrameworkCore.Metadata.Conventions.ConventionSet());
        context.OnModelCreating(modelbuilder);
        IMutableModel model=modelbuilder.Model;

from there I used Linq to transform the various info about each entity's properties and the annotations on them into List<KeyValuePair<string,List<KeyValuePair<Regex,string>>>> where the first pair's key is the entity name, and the value is a list of find and replace pairs to edit the code that had already been generated with the corresponding validation, one per property. Then all I had to do was abuse the fact that the tooling generates the classes in <className>.cs files, and iterate over my list, executing the replacements for each entity source code file.

I'd have preferred doing something a little less hacky, because I'm relying on format that the ef tooling outputs, but it works

Upvotes: 0

Smit
Smit

Reputation: 2459

EntityFramework Core does not enforce any validation at all. The validation rules you see in the example are enforced by MVC and not EF. One of the main reason for EF Core to remove validation check was that only. Validation are run in UI and then in EF and then again in database which is just redundant. Hence client side validation is left to the front-end (MVC in this case) and server side is done by database engine.

When you use database first approach, EF core does not generate any annotation for validation because it does not reason about them anyway. That means you would get only server side validation which means error during SaveChanges.

The only way to enforce constraint in the code (client side) is to write those annotations so that MVC can enforce them or write custom code to deal with it. The whole validation mechanism is transparent to EF.

Upvotes: 1

Related Questions