Advertisement

#6 The Domain Database Using Entity Framework

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.

We need an entity

  • WebUi
    • Domain
      • Article.cs

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; }
    }
}
(a) The first entity that we need a model for our database is an article.

The context

  • WebUi
    • Domain
      • DomainContext.cs

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; }
    }
}
(b) The domain context will allow us to have access to the actual data contained within the database.

The repository interface

  • WebUi
    • Domain
      • IDomainRepository.cs

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; }
    }
}
(c) Our repository interface which exposes the article DbSet.
Advertisement

The repository

  • WebUi
    • Domain
      • DomainRepository.cs

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();
        }
    }
}
(d) The concrete repository class that implements our repository interface.

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"
  },
  ...
}
(e) The localdb connection string for our domain repository.

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>();
            ...
        }
        ...
    }
}
(f) It is finally time to associate in our domain connection string with the domain context. And to associate the domain repository interface with our domain repository class.

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).

The error that we will receive when we try to create our intial migration.
(g) The error that we will receive when we try to create our intial migration.

If only the solution was always to simple

  • WebUi
    • Domain
      • DomainContext.cs

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)
        {
            
        }
        ...
    }
}
(h) Modifying our domain context to accept options when being constructed and passing them to the base class.

With that done if we once again run the Add-Migration InitialMigration command in the package manager console we should see (i).

(i) Image showing that we have successfully created our initial migration.

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.

Exciton Interactive LLC
Advertisement