As we start down the code-first path, there are a couple of things that could be true. If we already have a database, then we will need to configure our objects to that schema, but what if we do not have one? That is the subject of this recipe: creating a database from the objects we declare.
We will be using the NuGet Package Manager to install the Entity Framework Core 1 package, Microsoft.EntityFrameworkCore
. We will also be using a SQL Server database for storing the data, so we will also need Microsoft.EntityFrameworkCore.SqlServer
.
To mock interfaces and base classes, we will use Moq
.
Finally, xunit
is the package we will be using for the unit tests and dotnet-text-xunit
adds tooling support for Visual Studio. Note that the UnitTests
project is a .NET Core App 1.0 (netcoreapp1.0), that Microsoft.EntityFrameworkCore.Design
is configured as a build dependency, and Microsoft.EntityFrameworkCore.Tools
is set as a tool.
Open Using EF Core Solution from the included source code examples.
Execute the database setup script from the code samples included for this recipe. This can be found in the DataAccess
project within the Database
folder.
First, we write a unit test with the following code in a new C# file called
DatabaseTest.cs
, in theUnitTests
project:using BusinessLogic; using Xunit; using DataAccess; namespace UnitTests { public class DatabaseTest : BaseTest { [Fact] public void CanCreateDatabase() { //Arrange var connectionString = Configuration["Data:Blog:ConnectionString"]; var context =new BlogContext(connectionString); //Act var created = context.Database.EnsureCreated(); //Assert Assert.True(created); } } }
We will need to add a connection string to the
UnitTests
project to our database; we do so by providing an identicalappSettings.json
file to the one introduced in the previous recipe:{ "Data": { "Blog": { "ConnectionString": "Server=(local)\\SQLEXPRESS;Database=Blog;Integrated Security=SSPI;MultipleActiveResultSets=true" } } }
In the
DataAccess
project, we will use the C#BlogContext
class that was introduced in the previous chapter:using Microsoft.EntityFrameworkCore; using BusinessLogic; namespace DataAccess { public class BlogContext : DbContext { private readonly string _connectionString; public BlogContext(string connectionString) { _connectionString = connectionString; } public DbSet<Blog> Blogs { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer(_connectionString); base.OnConfiguring(optionsBuilder); } } }
Entity Framework will initialize itself by calling the OnConfiguring
method whenever it needs to get data; after that, it knows about the database to use. The EnsureCreated
method will make sure that the database either already exists or is created in the moment.
When we start a green field project, we have that rush of happiness to be working in a problem domain that no one has touched before. This can be exhilarating and daunting at the same time. The objects we define and the structure of our program come naturally to a programmer, but most of us need to think differently to design the database schema. This is where the tools can help to translate our objects and intended structure into the database schema if we leverage some patterns. We can then take full advantage of being object-oriented programmers.
A word of caution: previous versions of Entity Framework offered mechanisms such as database initializers. These not only would create the database, but also rebuild it, in case the code-first model had changed, and even add some initial data. For better or worse, these mechanisms are now gone, and we will need to leverage Entity Framework Core Migrations for similar features. We will discuss Migrations in another recipe.