# Database Context

Add the `ConnectionStrings` to the `appsettings.json` pointing to the local install of the PostgreSQL like seen below.

{% code title=".\appsettings.json" %}

```
{
	"Logging": {
		"LogLevel": {
			"Default": "Information",
			"Microsoft": "Warning",
			"Microsoft.Hosting.Lifetime": "Information"
		}
	},
	"AllowedHosts": "*",
	"ConnectionStrings": {
		"SlackCloneDb": 
		"Username=postgres;Password=postgres;Host=localhost;Database=SlackCloneDb;"
	}
}

```

{% endcode %}

Next we need to create a DbContext, create a `SlackCloneDbContext.cs` file in the Entities folder.

{% code title=".\Entities\SlackCloneDbContext.cs" %}

```csharp
using Microsoft.EntityFrameworkCore;
using System;

namespace SlackClone.Entities
{
    public class SlackCloneDbContext : DbContext
    {
        public SlackCloneDbContext(
            DbContextOptions<SlackCloneDbContext> options) : base(options) { }

        // Creates the Tables
        public DbSet<User> Users { get; set; }
        public DbSet<UserStatus> UserStatuses { get; set; }
        public DbSet<DirectMessage> DirectMessages { get; set; }
        public DbSet<Channel> Channels { get; set; }
        public DbSet<ChannelMessage> ChannelMessages { get; set; }
        public DbSet<ChannelChannelMessage> ChannelsChannelMessages { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // Allows auto generation of UUID
            modelBuilder.HasPostgresExtension("uuid-ossp");

            // Many to Many Table Mapping
            modelBuilder.Entity<ChannelChannelMessage>()
                .HasKey(bc => new { bc.ChannelId, bc.MessageId });
            modelBuilder.Entity<ChannelChannelMessage>()
                .HasOne(bc => bc.Channel)
                .WithMany(b => b.ChannelsChannelMessages)
                .HasForeignKey(bc => bc.ChannelId);
            modelBuilder.Entity<ChannelChannelMessage>()
                .HasOne(bc => bc.ChannelMessage)
                .WithMany(c => c.ChannelsChannelMessages)
                .HasForeignKey(bc => bc.MessageId);

            // Generates random uuid for Id fields
            modelBuilder.Entity<User>().Property(p => p.Id)
                .HasDefaultValueSql("uuid_generate_v4()");
            modelBuilder.Entity<UserStatus>().Property(p => p.Id)
                .HasDefaultValueSql("uuid_generate_v4()");
            modelBuilder.Entity<ChannelMessage>().Property(p => p.Id)
                .HasDefaultValueSql("uuid_generate_v4()");
            modelBuilder.Entity<Channel>().Property(p => p.Id)
                .HasDefaultValueSql("uuid_generate_v4()");

            // Creates initial data for user statuses    
            modelBuilder.Entity<UserStatus>().HasData(
                new UserStatus
                {
                    Id = Guid.NewGuid(),
                    Status = "Available",
                    Description = "User is online",
                    Rank = 1,

                },
                new UserStatus
                {
                    Id = Guid.NewGuid(),
                    Status = "Busy",
                    Description = "User is busy",
                    Rank = 2,
                },
                new UserStatus
                {
                    Id = Guid.NewGuid(),
                    Status = "Do Not Disturb",
                    Description = "User oes not want to be disturbed",
                    Rank = 3,
                },
                new UserStatus
                {
                    Id = Guid.NewGuid(),
                    Status = "Away",
                    Description = "User is away",
                    Rank = 4,
                },
                new UserStatus
                {
                    Id = Guid.NewGuid(),
                    Status = "Offline",
                    Description = "User is offline",
                    Rank = 5
                }
            );

            // Creates an initial general channel
            modelBuilder.Entity<Channel>().HasData(
                new Channel { Id = Guid.NewGuid(), Name = "general" }
            );
        }
    }
}

```

{% endcode %}

Once the DbContext is created, its time to create migrations and update the database to create the initial tables, relationships and data.

Before you can perform migrations you need to install `dotnet-ef` tools.

```bash
dotnet tool install --global dotnet-ef
```

After `dotnet-ef` tools are installed, we can create the initial migrations by typing the following command.

```bash
dotnet ef migrations add InitialDbCreation
```

This will create db migrations in the `./Migrations` folder. After the migrations are created we need to update the database so the tables can be created, this can be done using the following command.

```csharp
dotnet ef database update
```

If all has gone well you can use pgAdmin to view the database we just created like seen below.

![](https://3683023892-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LurxKF9uo_T_1SndGac%2F-LuxmdJOxlTrIYKbxSwC%2F-LuxqTuMAMMCgRJ00Iz9%2Fimage.png?alt=media\&token=de063780-85c4-4f26-97a0-4245fba7d7ca)
