In this article you’re going to learn what is a mysterious <DBName>Snapshot.cs file in your solution. I’m going to teach you why snapshot file exists and how it relates to migrations.

Introduction to migrations

You create new app which requires a database. But you change the model (classes) often so every time you change your model (e.g. you add new column) you need to update your database schema. It’s a lot of work, but there’s a way to automate it.

We can use migrations to automate this scenario. Migration basically is a file which tells what changes has been made in your data model. Because of it EF knows how to update your database schema to match current model. Migrations keep your data model and database in sync.

Each migration contains two methods Up and Down. Former is used to update database, latter for downgrade (in case of a wrong migration you can revert changes).

This is how a sample migration looks like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using System;
using System.Collections.Generic;

namespace SOLUTION.Migrations
{
    // migration name: Added books (table)
    public partial class AddedBooks : Migration
    {
        // what to do in case of an ugprade
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            // create new table: Books
            // with columns: Id (int; identity) and Name (string; nullable)
            // and make a PK on Id column
            migrationBuilder.CreateTable(
                name: "Books",
                columns: table => new
                {
                    Id = table.Column<int>(nullable: false)
                        .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                    Name = table.Column<string>(nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_EmployeeClothes", x => x.Id);
                });
        }

        // what to do in case of an downgrade
        protected override void Down(MigrationBuilder migrationBuilder)
        {
            // simply drop the table
            migrationBuilder.DropTable(
                name: "Books");
        }
    }
}

It’s also worth pointing out that migrations are also very important during deployment. You develop locally, but once you deploy your application the database should also match new data model. Since it’s automated by migrations you don’t have to do it manually. Though, it requires caution, wrong migrations can break your application. You need to be carefull especially with foreign keys (relationships in general). It can cause null reference exceptions or it may not be able to apply migration because of other referential constraint. So, wrong migration can break your app either on your server side or database (schema) level.

The snapshot

When you start adding migrations you should notice that there is a new file inside your solution. It’s called <DbContext>Snapshot.cs. This file holds a snapshot of a current schema. It’s like a single class which translates your model to database schema. Once you create a migration EF looks for difference between data model and a snapshot file. It is also used when you need to remove migration.

The snapshot is also important for teams. Imagine multiple programmers working on same data model. Everyone makes some kind of change, there must be a way to synchronize differences. It works most of the time, but don’t expect it to work in every single scenario. It’s impossible to synchronize it all the time, because there are mutually exclusive scenarios (e.g. one person renames column, other person removes it). At times human intervention is still required.