Entity Framework - bradleypeterson/timetracker GitHub Wiki

Entity Framework

Just a note

Honestly guys while I can talk all day about Entity Framework it really wont do it justice or help you understand besides maybe at a very high level. You will just need to start learning about it and using it to gain a true understanding of what it will do for you. At the bottom of this document I have included several links to resources that are incredibly helpful to learn what EF Core is and does. Even if you don't understand it fully it will help you be more prepared for what we in the Industry generally use to connect with databases. While you wont always use a tool like Entity, the patterns used by it will help you understand better practices to use when you don't have the benefit of an ORM at your disposal.

With that being said lets dive in and I will do my best to explain what EF Core is and how to use it.

What Is Entity Framework

Essentially Entity Framework is a database access tool. It will automatically map tables to what are known as entities. These entities are a representation of what the database tables would look like if they were objects. It will then use C# attributes to denote additional meta data about each of the properties (columns in the database) and will apply those settings to the next migration (learn more about migrations). Entity Framework uses these mappings and allows you to save data and retrieve data to and from your database using code rather than sql. While this means that you can take a performance hit at times for the most part the development time saved and the ease of use make this worth it.

Entity Framework is an ORM or Object Relational Mapper. It is similar to that of NHibernate for C# or Hibernate for Java. The purpose of Entity Framework or as I will call it from now on EF, is to remove the complexity of dealing with tying objects from your backend to your database. As this is rather difficult to do given a Relational database is not meant to model how your application uses data but rather to model the relationships of the data you will be using in your Domain of knowledge.

This is accomplished by creating what are known as Entities. Entities are effectively POCOS (Plain Old C# Objects) this means that they should not have functions or methods to handle business logic inside of them. You would instead move that business logic into a Domain object.

Why are we using it

We are using EF Core so that we do not need to worry about building manual sql queries to deal with the database. As well as make it far easier for new developers to be on boarded. The on boarding process becomes much easier due to being able to run migrations which allow us to take a existing database connection (there doesn't need to be an existing database on the other end, just a connection to a database server) and build a database with all of the needed schema and seed data that the system would require. This way a new developer only needs to run a single command on their environment and they will have a database up and running without needing to deal with sql at all. In the end this will make your life easier and allow you to rapidly iterate changes without being affrade of needing to change how the existing database schema works.

Things to know about our version

We are using the SQL Adapter for PostgreSQL which is a database similar to that of MySQL. However, it has a few more tools that are similar to that of SqlServer and is free to run commercially. If you determine that going forward you need to switch out what database you are using (for example to SqlServer) I would recommend moving much of the data into a DAL (Data Access Layer) and decoupling it from the current web server instance. This can be done using the repository pattern possibly with the Unit of Work pattern.

Migrations

What are they

A migration in the context of EF Core is a class with a name and unique identifier associated to it. This class is specifically designed to speak the language of EF Core's SQL mapping language. It represents a path or node on the way to a specific state of the database. Each migration represents the state of the database at that moment in time. Each migration will contain the needed information to go from the previous migration "up" to its state as well as back "down" to the state just before. Now you might wonder wont that make a migration complex and filled with a lot of data about the database, well you would be correct and in fact are very correct. Database migrations can quickly become overwhelming to work with which is why it is generally a very good practice to make a small change and then build a migration.

For example:
When needing to update a date from an string to a date and make it required. You should first make the change going from a string to a date, this is now one migration. Then you would make a migration for making the date required. The reasons for this are, that you keep the migration size smaller, and you make it easier for you to determine where a change failed. This means that finding problems in your database schema become much easier as you aren't looking at 50 different changes just one or two.

Building Migrations

When building a new migration keep in mind that there are 2 important functions in every migration for EF Core. Those functions are the Up and Down functions. The Up function brings the database Up to the state of the migration that it is a part of. The Down function will undo any changes made in the Up function. Keep this in mind when you are building migrations, as this is very important to handle. It is important that the Down function always undoes whatever new state is created by the Up function and should be the exact opposite of that function. But not only should it be the opposite but it should bring the database to a state that is expected by the application in that situation.

Migration Documentation

Dealing with dates

If you need to upgrade a string type to a DateTime in the dotnet entities refer to the following migrations and documentation for examples.

Raw SQL

You should attempt to avoid any and all raw SQL statements as much as possible. Any statement you can do in the ORM you should do. If an statement being auto generated by the ORM is becoming so complicated that it is not reasonable to run via the ORM then you should build a migration that adds a Stored Procedure. Then you should use EF Core to call the stored proc when you need to run that particular set of data. For this project this should not be a common thing that happens.

Useful Commands and Information

The following are some useful commands to know with EF Core. The best place to learn about these commands is the Microsoft documentation.

Command Description
dotnet ef migrations add <name> Generate a new migration with name
dotnet ef database update [id] Update database in connection string to latest migration available or [id] if supplied
dotnet ef migrations remove Removes the most resent migration if it has not yet been applied to database

Example:

You may use the command line (.NET core CLI) to create and add a migration. In order to update the database you must make changes in the project and do a migration.

For example, if you wanted to add an email column to the Users table you would go into the Users model within the project and add the column. Ensure the column will be mapped. Now in order to see this transferred over into your database you will need to add a migration by running: dotnet ef migrations add MIGRATIONNAME To update the database to reflect the changes run this command: dotnet ef database update

This is an additional resource that can has a more detailed information and examples.
https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/?tabs=dotnet-core-cli

Learn More

Best way to learn Entity Framework is just to start reading the docs on microsoft's web site and if you have access to Pluralsite check out courses by Julie Lerman (The Leading Expert) or Mosh Hamedani.

Documentation and Links

⚠️ **GitHub.com Fallback** ⚠️