When to use code first approach in entity framework

When it comes to developers talking about Entity Framework (and I’m including EF Core in this), I find there is very much two camps. There are the developers who find EF intuitive and easy to use, and those who say it is absolute hell to manage. But what I started finding was that it all depended on the “approach” to using Entity Framework. By approach, I mean whether to use Code First, Database First, or Model First.

There is some historical damage mixed in here because even though I include Model First in this list, the support for this approach was dropped some years back. But people who endured the days of using that annoying WYSIWYG editor in Visual Studio to manage their database to this day will tell you that EntityFramework is a pile of junk and they will never touch it, even though things like Code First has improved leaps and bounds from where it was.

I’m not going to play off these approaches against each other for the most part, but I want to explain what each one actually means, and why people’s perception of Entity Framework can be very different depending on their usage.

What Is Entity Framework Code First?

If you’ve used EF Core or later versions of Entity Framework, you’ve probably used “Code First”. The “Code First” approach refers to scaffolding out your database using C# classes, and then using entity framework to “migrate” your database using commands such as :

Update-Database

or

dotnet ef database update

Because everything is managed from C# code, when you want additional SQL types such as indexes, constraints or even just complex foreign keys, you must use either the Data Annotation attributes or the Entity Framework Fluent Configuration. Infact, we have a pretty good guide (If we do say so ourselves), on some really clean ways to approach configuring your database using a Code First approach here : https://dotnetcoretutorials.com/2020/06/27/a-cleaner-way-to-do-entity-configuration-with-ef-core/

The main thing to understand about Code First is that because you are scaffolding the database using C# code, it works well for developers, but not for DBAs or Architects. It can be hard to map out a database schema to the 9th degree when everything is written in C#. Additionally, if you have DBA’s who love things like stored procedures or views, while these are doable in Code First, it can become unwieldy very fast.

The benefits of using a Code First approach are numerous :

  • Your code is always talking to a database schema that it has control over, therefore there is rarely a “mismatch” in column types, table definitions etc.
  • You have an out of the box way to manage database migrations (So no dodgy “run this script before go live” type go live run sheets)
  • Almost anyone can scaffold a database if they know C#, even without having too much knowledge of SQL in general (Although.. this can be a negative)
  • A code first approach works across different databases such as Postgres, MySQL etc

In general, you’re probably going to use a Code First approach for almost every new .NET project these days. Even if the end goal is to manage the database in a different way post go live, it’s such a rapid prototyping tool that scales pretty well, so you’re going to want to be using it.

What Is Entity Framework Database First?

Database First is an interesting approach because it use to be a lot more prevalent. Whether it was called database first before, or just datasets in general if you come from a WinForms background, it simply refers to getting your application to talk to a database that already exists.

I’ll give you an example. If there is a database of a production system, that already has say 50+ tables, and each of those tables has your usual columns, foreign keys, and constraints. If we took a code first approach there is a couple of problems :

  • We have to manually type out each definition of the tables we want to use, and we have to do our best to line them up perfectly.
  • We can’t use code first migrations because the database already exists and is likely to be under management in a different way. While not a problem, one of the huge boons of using Code First is lost on us.

So *could* we write a code first approach, but it’s somewhat lying to ourselves that the code came first.

So instead, we can use a Database First approach. All this does is creating what we would have done manually in code, but it does it by inspecting the database and essentially creating the classes for us. If you use certain ORM’s back in the day, this was fairly common to use an “auto generated” type database ORM that you could re-generate each time the database changed.

To do this, all we have to do is run the following command :

Scaffold-DbContext "MyConnectionStringHere"

And Entity Framework will do the rest for us. We can run this command again over time to pick up the latest changes to our database schema if we need to. Because of this, it is not advisable to ever edit the classes that Entity Framework generates for us as these will be overwritten the next time a scaffolding is run.

The official documentation from Microsoft has moved the “Database First” approach under a page titled “Reverse Engineering” which is pretty apt : https://docs.microsoft.com/en-us/ef/core/managing-schemas/scaffolding

When we go and talk about Model First approaches shortly, it should also be noted that you could use a Database First approach even when you were using a Model as well. All Database First refers to is auto generating your schema in Visual Studio, whether that be C# classes or an EDMX file.

What Is Entity Framework Model First?

If you’ve ever talked to someone who used Entity Framework five-ish years ago, they will talk about the “designer” and the “edmx file” and how it was a slow, laggy, buggy piece of software. And they weren’t wrong.

Here’s what it looked like :

When to use code first approach in entity framework

It was essentially a designer for building out a database schema, from inside Visual Studio. The problem was that the designer was very very laggy when you got over a couple of dozen tables. This designer however was all built over this thing called an “edmx” file. An edmx was essentially this huge XML file that described the database schema. It looked a bit like so :

When to use code first approach in entity framework

What would often happen is that instead of using the laggy designer to make changes, people would edit this XML directly to make changes, then if they could, open the designer check if it looked right before checking in their change. It was often a joke around the office if you accidentally opened the designer because at best, your Visual Studio could be frozen for a few minutes, and at worst it would be frozen for several minutes then just crash.

The EDMX file wasn’t the only file of the Model First approach. Based on the EDMX, Visual Studio would also auto generate other C# files to tie into your code that probably wouldn’t be too dissimilar from the code files we use when doing a Code First approach, except they were an auto generated mess.

Other than the laggy designer, there were some other issues with a Model First approach :

  • It did not do Database Migrations, you often had to use a third party tool for that.
  • When working with a larger team, because the entire database is in one big EDMX file, merge conflicts were rife and a nightmare to work out
  • Some of the auto generated files wouldn’t happen automatically, you would have to right click your EDMX and then select “Generate” etc. If you forgot this, then things went haywire.

In general, the Model First died off some years back and was never added back to EF Core, so it’s unlikely you’ll run into it these days. But it’s still good to know that when people are complaining about how bad Entity Framework is with the “edmx” file, they are talking about a legacy offering, not today’s Code First Entity Framework.

Which Approach To Use?

These days, it’s a fairly simple equation.

  • If you are starting a new project, with a new database, use EF Core Code First
  • If you are starting a new project, but there is an existing database you want to talk to, use EF Core Database First.