#6 The Domain Database Using Entity Framework
Saturday, November 24, 2018
In this article we will define a class that will represent the data within a table of a SQL server database. We will also create the context that will allow us to interact with the database and a repository class that we can inject into other code that will give us access to the data through the context. Finally we will use entity framework to create our database and table for us without us having to write any SQL code.
Parts
- Part 29: Offset Pager Urls
- Part 28: Offset Pager Start
- Part 27: Mock Context Builder
- Part 26: Mock Repository
- Part 25: Mock Async
- Part 24: Picture Tag Helper
- Part 23: Img DPR Tag Helper
- Part 22: Img Responsive Tag Helper
- Part 21: Img Optimized Display
- Part 20: Img Optimization
- Part 19: Img Lazy Loading
- Part 18: Img Responsive
- Part 17: Bottom Nav
- Part 16: Main Nav Cookie
- Part 15: Main Nav Mobile
- Part 14: Main Nav Search
- Part 13: Main Nav Auth
- Part 12: Main Nav Anchors
- Part 11: Main Nav Logo
- Part 10: Search Results
- Part 9: Search Manager
- Part 8: Search Start
- Part 7: Seeding the Database
- Part 6: Domain Database
- Part 5: Emailing Exceptions
- Part 4: Mailkit
- Part 3: View Renderer
- Part 2: Upgrade to 2.1
- Part 1: Quick Start
We need an entity
- WebUi
- Domain
- Article.cs
- Domain
The first step that we will take in setting up a database for our application is to define an entity to represent the data that we wish to store. Not suprisingly we are going to model an object that I have a bit of history with and it will be helpful for future functionality. That object is an article (a).
Article.cs
using System;
namespace WebUi.Domain
{
public class Article
{
public string Author { get; set; }
public DateTime Created { get; set; }
public int Id { get; set; }
public string Title { get; set; }
}
}
The context
- WebUi
- Domain
- DomainContext.cs
- Domain
Now that we have an entity specified we can turn to creating the database context give us access to the actual
data within our database (b).
For the moment all we need to do is create a class that derives from DbContext
as shown. We actually do need to do one more thing but we will see that very shortly.
DomainContext.cs
using Microsoft.EntityFrameworkCore;
namespace WebUi.Domain
{
public class DomainContext : DbContext
{
public DbSet<Article> Articles { get; set; }
}
}
The repository interface
- WebUi
- Domain
- IDomainRepository.cs
- Domain
Like most things in life there are many choices that we need to make. In this case we are going to expose the
DbSet
itself within through our repository. This will mean later on that
we will filter, sort, and whaterver else we want directly from whatever class consumes the repository. You could
of course change things so that there would be a query or list method within the repository itself. But at least
for now what we are going with is shown in (c).
IDomainRepository.cs
using System;
using Microsoft.EntityFrameworkCore;
namespace WebUi.Domain
{
public interface IDomainRepository : IDisposable
{
DbSet<Article> Articles { get; }
}
}
The repository
- WebUi
- Domain
- DomainRepository.cs
- Domain
And of course we need to implement the interface that we just created (d). In addition to giving us access to our articles we will also use the repository to dispose of any connections that we have and save any changes that we make.
DomainRespository.cs
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;
namespace WebUi.Domain
{
public class DomainRepository : IDomainRepository
{
private readonly DomainContext _domainContext;
public DomainRepository(DomainContext domainContext)
{
_domainContext = domainContext;
}
public DbSet<Article> Articles => _domainContext.Articles;
public void Dispose()
{
_domainContext?.Dispose();
}
public async Task<int> SaveChangesAsync()
{
return await _domainContext.SaveChangesAsync();
}
}
}
Which database are we talking about?
- WebUi
- appsettings.json
In order to specify which database we are working with we need to define the connection string. For our purposes
we will use a localdb
instance with the connection string showed in
(e).
appsettings.json
{
"ConnectionStrings": {
"DomainConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-core-2-domain;Trusted_Connection=True;MultipleActiveResultSets=true"
},
...
}
Last but not least configuring startup
- WebUi
- Startup.cs
The last thing we need to do is to tell entity framework which connection string to use for our domain context as well as let asp.net know what object to serve up when we ask for an object that implements our repository interface (f).
Startup.cs
...
using Microsoft.EntityFrameworkCore;
...
using WebUi.Domain;
...
namespace WebUi
{
public class Startup
{
...
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContextPool<DomainContext>(x =>
x.UseSqlServer(Configuration.GetConnectionString("DomainConnection")));
...
services.AddTransient<IDomainRepository, DomainRepository>();
...
}
...
}
}
Does it work?
Given the question asked above the answer is probably no it does not work. At least not yet. If we try to add our
initial migration using Add-Migration InitialMigration
in our package manager
console we will be greeted with the error shown in (g).
If only the solution was always to simple
- WebUi
- Domain
- DomainContext.cs
- Domain
I mentioned when we first created our domain context that there was one more thing that we needed to do and now is the time to do it. That thing is to add a simple constructor to our context that takes in options and passes them to the base class (h).
DomainContext.cs
...
namespace WebUi.Domain
{
public class DomainContext : DbContext
{
public DomainContext(DbContextOptions<DomainContext> options)
: base(options)
{
}
...
}
}
With that done if we once again run the Add-Migration InitialMigration
command
in the package manager console we should see (i).
If we check the root of our project we should see a migrations folder which contains the code for our migration. To
actually apply our migration, which will create our database, we just need to run the
Update-Database
once again in the package manager console. With that done our
database should have been created. You check to make sure either using Visual Studio's Server Explorer window or
SQL Server Management Studio. For either case the server name is
(LocalDb)\MSSQLLocalDB
.