Introduction
In the previous articles (data access approach, code first approach, and WebAPI) we learned a lot about the Entity Framework and its practical implementations. The intent of this article is to explain the concept of Entity Framework core. We’ll go step by step to explore the topic of Entity Framework core. We’ll explore the code first approach using EF Core and learn about data annotations as well. We’ll also cover code first migrations in this article along with an understanding of how to seed the database. I’ll use Visual Studio 2017 for the tutorial. For the database, we would be using SQL Server. You can make use of local dB if you do not have SQL server installed.
Series Info
We'll follow a five-article series to learn the topic of Entity Framework in detail. All the articles will be tutorial form except the last where I'll cover the theory, history, use of Entity Framework. Following are the topics of the series.

- Learning Entity Framework (Day 1): Data Access Approaches of Entity Framework in .NET
- Learning Entity Framework (Day 2): Code First Migrations in Entity Framework in .NET
- Learning Entity Framework (Day 3): NET Web API 2 with Entity Framework 6 Code First Migrations
- Learning Entity Framework (Day 4): Code First Approach using Entity Framework Core in .NET
- Learning Entity Framework (Day 5): Entity Framework (The Theory)
Entity Framework Core
EF Core is also an ORM, but it's not an upgrade to Entity Framework 6, and it shouldn't be regarded as such. Instead, Entity Framework Core is a lightweight, extensible, and cross-platform version of Entity Framework. Therefore, it comes with a bunch of new features and improvements over Entity Framework 6, and it's currently at version 2. For ASP.NET Core 1, version 1 should be used, and for ASP.NET Core 2, version 2 is advised. Entity Framework does not support all the features of Entity Framework 6. Entity Framework Core is recommended for new apps that don't require the heavy set of features Entity Framework 6 offers, or for apps that target .NET Core. It comes with a set of providers which could be used with a variety of databases. It could be used with Microsoft SQL Server, of course, but also with SQLite, Postgre, SQL Server Compact Edition, MySQL, and IBM DB2. And there's also an in-memory provider for testing purposes. EF Core can be used both for a code-first approach, which will create the database from the code, or a database-first approach, which is convenient if the database is already there. The following section will show the basic implementation of Entity Framework Core in a console application and of course, it could be used in any type of .NET application like MVC, Web API, Windows which needs to interact with the database. We'll start out by adding an EF Core it to our project. We'll also investigate migrations, a way to migrate between different versions of our underlying datastore. We’ll also check out how we can seed the database with data from code. Let's dive in by introducing Entity Framework Core.
Where can EF Core be Used
Entity Framework Core runs on .NET Core, and .NET Core runs in a lot of places. It runs inside of the full .NET Framework that is any version that is 4.5.1 or newer, and .NET Core itself can run on the CoreCLR, that's the runtime, and CoreCLR can run natively, not only in Windows but also on Mac and Linux. And the other place you can use EF Core on the Universal Windows Platform, or UWP for Windows 10, so that runs on any device or PC that can run Windows 10, but that doesn't necessarily mean you should use Entity Framework Core in all of these scenarios, and that's a really important point to keep in mind because Entity Framework Core is a brand new set of APIs, it doesn't have all of the features that you might be used to with Entity Framework 6, and while some of those features will be coming in future versions of EF Core, there are a few that will never be part of Entity Framework Core, so it's important to understand that, and that you may not want to start every single new project with the Entity Framework Core. Be sure that Entity Framework Core has the features that you need. If you want to target cross-platform or UWP, you have to use Entity Framework Core, but for .NET apps, you can still use Entity Framework 6, and in fact for ASP.NET Core apps that will definitely stay on Windows, in other words on a Windows Server, you can still build separate APIs using full .NET with the Entity Framework 6, and just have your ASP.NET Core app talk to that Entity Framework 6-based library.
Code First Approach using Entity Framework Core
Data access approaches are same in Entity Framework 6 and Entity Framework Core apart from some of the new features that EF Core provides. There are minor differences and implementation techniques that come along with the related packages. Let’s see the EF Core in action step by step using code first approach. We’ll cover more topics like data annotations and other migration techniques while walking through practical implementation.
Adding Entities
- Like explained, for code first approach, the application should have entities that would eventually result in the database tables. So, create a console application to start within .NET Framework 4.6.2. Name the application EmployeeManagement and solution name as EFCore.

- Add two entity classes one named Department and other as Employee. There would be one too many relationships between department and employee i.e. a department can have multiple employees and an employee would be associated with any one department.
Department

Code
- namespace EmployeeManagement
- {
- public class Department
- {
- public int DepartmentId { get; set; }
- public string DepartmentName { get; set; }
- public string DepartmentDescription { get; set; }
- }
- }
Employee

Code
- namespace EmployeeManagement
- {
- public class Employee
- {
- public int EmployeeId { get; set; }
- public string EmployeeName { get; set; }
- public int DepartmentId { get; set; }
- public virtual Department Departments { get; set; }
- }
- }
- The department entity has a department name and description property and the entity employee has EmployeeId, Name and DepartmentId property that acts as a navigation property for departments. Add a property Employees denoting the collection of employees in the Department entity as the department can have many employees. Similarly, a property of type Department is added in Employee class that returns a single department and not the list.

- public virtual ICollection < Employee > Employees {
- get;
- set;
- }
Data Annotations
- By giving the class an ID with name Id, this field is automatically regarded as the primary key. DepartmentId, i.e., the class name, followed by ID would be possible as well. If we would name this differently, the convention doesn't apply. But we can apply the key data annotation from System.ComponentModel.DataAnnotations. Personally, I like to apply the key annotation anyway, even if convention would ensure this property would be regarded as primary key, I feel it makes Entity classes so much more understandable at first glance. But, well, I've got the same gripe with a lot of convention-based approaches, so this is totally up to you. Following is the way in which you can add a [Key] for the property you want to make a primary key.

- Similarly, add the key for EmployeeId i.e. a primary key for Employee entity.

- Another thing of importance is a generation of ID primary keys. By convention, primary keys that are of integer or GUID data type will be set up to have their values generated on add. In other words, our ID will be an identity column. To explicitly state this, we can use another annotation, the database-generated annotation from the ComponentModel.DataAnnotations.SchemaNamespace. It has three possible values,
- null for no generation,
- identity for generation on add,
- computed for generation on add or update.
We need the identity option. A new key will be generated when an Employee is added. How this value is generated depends on the database provider being used. Database providers may automatically set up value generation for some property types, while others will require you to manually set up how the value is generated. In our case, we'll be using SQL Server. So, we're good to go. A new integer primary key will be automatically generated without further setup.
- We want to signify the relationship between Department and Employee. If we look back at the Department entity, we already defined a collection of Employee, but we want to navigate through our object graph from a point of interest to the parent department. So, we need a property to refer to that parent department. And we need to state what the foreign key property will be. Again, there's a convention-based and an explicit approach possible. By convention, a relationship will be created when there is a navigation property discovered on a type. And a property is considered a navigation property if the type it points to cannot be mapped as a scalar type by the current database provider. So, if we add a property Department of type Department, this is considered the navigation property, and a relationship will be created. Relationships that are discovered by convention will always target the primary key of the principal And in this case, that's the ID of the Department. That will be our foreign key. It's not required to explicitly define this foreign key property on the dependent class. And the dependent class, well, that's our Employee class. But it is recommended, so we'll add one. So that's the convention-based approach. If we do not want the convention-based approach to be followed, which states that a foreign key will be named according to the navigation property's class name followed by id, so DepartmentId in our case, we can again use an annotation for that. The foreign key annotation from the System.ComponentModel.DataAnnotations.Schema namespace.

- The entity classes properties do not have any data annotation w.r.t mandatories or max lengths. If we leave our entity classes like this, our database columns will allow null for fields that should not be null. And we'll be off max and varchar length instead of a specific maximum size. It's best practice to ensure these field restrictions are applied at the lowest possible level. So, in our case, that's the database itself. This ensures the best possible integrity. So, let's apply these attributes. For Employee, the EmployeeName was required with a maxLength of 50. And for the Department entity, we want these as well. Let's make Name required with a maximum length of 50.
Code- using System;
- using System.Collections.Generic;
- using System.ComponentModel.DataAnnotations;
- using System.ComponentModel.DataAnnotations.Schema;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace EmployeeManagement
- {
- public class Employee
- {
- [Key]
- [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
- public int EmployeeId { get; set; }
- [Required]
- [MaxLength(50)]
- public string EmployeeName { get; set; }
- public int DepartmentId { get; set; }
- [ForeignKey("DepartmentId")]
- public virtual Department Department { get; set; }
- }
- }
Adding DB Context
In this section, we'll create a context to interact with our database and that context represents a session with the database, and it can be used to query and save instances of our entities. Our entity classes are just classes. We didn't need any extra dependencies to create those but the DBContext, that's part of Entity Framework Core. And we'll also need a provider. In our case, we'll use the SQL Server provider, so we can connect to a LocalDB instance.
- Let's open the NuGet Right click on the project and select “Manage NuGet Packages…” option.

- We want to look for the Microsoft.EntityFrameworkCore.SqlServer If we install that, the Entity Framework core dependencies will be added as well, so we'll have all we need for now.

- Select the latest stable version and click install.

- Accept the license agreement.

As you can guess by now, no need to do this when you're on ASP.NET Core 2 and you've referenced the Microsoft.AspNetCore.All package. That includes the necessary references for Entity Framework Core.
- Now let's add a new class, EmployeeManagementContext.

- Have the class inherit DBContext. DBContext can be found in the EntityFrameworkCore namespace. Bigger applications often use multiple contexts. For example, were we to add some sort of reporting module to our application, that would fit in a separate context. There's no need for all the entities that map to tables in a database to be in the same context. Multiple contexts can work on the same database. In our case, well, we only have two entities, so one context is sufficient.

- In this context, we now want to define DbSets for our entities. Such a DbSet can be used to query and save instances of its entity type. LINQ queries against a DbSet will be translated into queries against the database. Add two properties each for entity classes that we have returning DbSet of the entity.

Code- using Microsoft.EntityFrameworkCore;
- namespace EmployeeManagement
- {
- public class EmployeeManagementContext : DbContext
- {
- public DbSet<Employee> Employees { get; set; }
- public DbSet<Department> Departments { get; set; }
- }
- }
- How do we tell the context that which database it has to associate to? Well, that's through a connection string. We need to provide this connection string to our DBContext. In other words, we need to configure this DBContext. And there are essentially two ways of doing this. Let's open our EmployeeManagementContext again. The first way of doing this is through overriding the OnConfigure method on the DBContext. This has an optionsBuilder as a parameter. And that optionsBuilder provides us with a method--UseSqlServer. This tells the DBContext it's being used to connect to a SQL server database, and it's here that we can provide a connection string. So that's one way.

- protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- optionsBuilder.UseSqlServer("connectionstring");
- base.OnConfiguring(optionsBuilder);
- }
- But let's look at the other way--via the constructor. So, let's comment OnConfiguring out, and have a look at the DBContext The DBContext exposes a constructor that accepts DBContext options.

- So, let's add a constructor that calls this constructor overload. What this allows us to do, and what isn't possible when overriding the OnConfigure method, is that we can provide options at the moment we register our DBContext. And that's a more logical approach.

- public EmployeeManagementContext(DbContextOptions<EmployeeManagementContext> options) : base (options)
- {
- }
- To get the instance of this context class now, let’s add a new class named Initialize and add a static method responsible for returning context instance. The GetContext() method overload on these options, so we can use now--UseSqlServer. It's from the EntityFrameworkCore namespace, so let's add that using statement. And in this method, we can pass in the connection string. So, let's add a variable to hold this connection string for now. The next logical question is, What would that connection string look like? Well, we're going to be using local DB, as this is installed automatically together with Visual Studio. But if you have a full SQL Server installation in your network, it'll work as well. Just make sure you change the connection string accordingly. The name (localdb)\MSSQLLocalDB is the default instance name, but it can be different on your machine depending on whatever you inputted on install. So, if you're not sure, have a look at the SQL Server Object Explorer window. If you don't see that on your machine, you can find it underneath the View menu item.

- public class Initialize
- {
- public static EmployeeManagementContext GetContext()
- {
- var connectionString = @"Server=(localdb)\mssqllocaldb;Database=EmployeeManagementDB;Trusted_Connection=True;";
- DbContextOptionsBuilder<EmployeeManagementContext> options = new DbContextOptionsBuilder<EmployeeManagementContext>();
- options.UseSqlServer(connectionString);
- return new EmployeeManagementContext(options.Options);
- }
- }






























Fred VPosted Oct 13, 2020, 1:13 PM
Nice article on Ef core migrations. I've been using dotnet ef migrate script commands to do the same based on this article here https://windocks.com/ef-core-migration that automates EF core migrations with a dockerfile
abdelkrim Tabet AoulPosted Jul 29, 2019, 5:51 AM
It's sad that we are forced to remove the database before executing migrations and there is no way to update the existing database from project's code
Abhilash ABhiPosted Feb 11, 2019, 1:17 AM
List 14) My Database is created but not tables? I followed every instructions. What could be wrong?
Faisal PathanPosted Nov 23, 2018, 11:13 PM
Excellent content, Thanks for sharing :)