Entity Framework can be difficult to get started with: especially if you come from a background of accessing the database directly, it can seem like there are endless meaningless errors that appear. In this post, I try to set-up EF Core using a .Net Core Console application. In order to better understand the errors, we’ll just do the minimum in each step; and be guided by the errors.
The first step is to create a .Net Core Console Application.
NuGet Packages
To use Entity Framework, you’ll first need to install the NuGet packages; to follow this post, you’ll need these two (initially) [note]All the code prefixed with `PM>` should be entered into the Package Manager Console.[/note]:
PM> Install-Package Microsoft.EntityFrameworkCore
PM> Install-Package Microsoft.EntityFrameworkCore.Tools
Model / Entities
The idea behind Entity Framework is that you represent database entities, or tables as they used to be known, with in memory objects. So the first step is to create a model:
namespace ConsoleApp1.Model
{
public class MyData
{
public string FieldOne { get; set; }
}
}
We’ve created the model, so the next thing is to create the DB:
PM> Update-Database
In the package manager console.
First Error - DbContext
The first error you get is:
No DbContext was found in assembly ‘ConsoleApp1’. Ensure that you’re using the correct assembly and that the type is neither abstract nor generic.
Okay, so let’s create a DbContext. The recommended pattern (as described here) is to inherit from DbContext:
namespace ConsoleApp1
{
public class MyDbContext : DbContext
{
}
}
Okay, we’ve created a DbContext - let’s go again:
PM> Update-Database
Second Error - Database Provider
The next error is:
System.InvalidOperationException: No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider.
So we’ve moved on a little. The next thing we need to do is to configure a provider. Because in this case, I’m using SQL Server, I’ll need another NuGet package:
PM> Install-Package Microsoft.EntityFrameworkCore.SqlServer
Then configure the DbContext to use it:
public class MyDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
string cn = @"Server=.\\SQLEXPRESS;Database=test-db;User Id= . . .";
optionsBuilder.UseSqlServer(cn);
base.OnConfiguring(optionsBuilder);
}
}
And again:
PM> Update-Database
Third Error - No Migrations
Strictly speaking this isn’t an actual error. It’s more a sign that nothing has happened:
No migrations were applied. The database is already up to date. Done.
A quick look in SSMS shows that, whilst it has created the DB, it hasn’t created the table:
So we need to add a migration? Well, if we call ```
Add-Migration
here, we'll get this: [note]
If you've tried this:
Remove-Migration
Will revert it.
[/note]
![](images/EF-2.png)
That's because we need to tell EF what data we care about. So, in the DbContext, we can let it know that we're interested in a data set (or, if you like, table) called MyData:
``` csharp
public class MyDbContext : DbContext
{
public DbSet<MyData> MyData { get; set; }
Right - now we can call:
PM> Add-Migration FirstMigration
Fourth Error - Primary Key
The next error is more about EF’s inner workings.:
System.InvalidOperationException: The entity type ‘MyData’ requires a primary key to be defined.
Definitely progress. Now we’re being moaned at because EF wants to know what the primary key for the table is, and we haven’t told it (Entity Framework, unlike SQL Server insists on a primary key). That requires a small change to the model:
using System.ComponentModel.DataAnnotations;
namespace ConsoleApp1.Model
{
public class MyData
{
[Key]
public string FieldOne { get; set; }
}
}
This time,
PM> Add-Migration FirstMigration
Produces this:
public partial class FirstMigration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "MyData",
columns: table => new
{
FieldOne = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK\_MyData", x => x.FieldOne);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "MyData");
}
}
Which looks much more like we’ll get a table - let’s try:
PM> update-database
Applying migration '20180224075857\_FirstMigration'.
Done.
PM>
Success
And it has, indeed, created a table!
References
https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/powershell
https://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext
https://www.learnentityframeworkcore.com/walkthroughs/console-application