So i wanted to add a simple migration for a comments table for my articles.
In Umbraco 8 they make it easy with components and their UmbracoKeyValues table.
In simple terms it works with three things, Component, Migration and schema.
The component is where you register your Migration to the “migration plan” aka. the UmbracoKeyValues table.
The migration is where the migration happens, and checks if it should even run it.
And lastly the Schema which is a representation of what you want to create along with some data attributes and so on.
Lets start with the Schema:
[TableName("ArticleComments")]
[PrimaryKey("Id", AutoIncrement = true)]
[ExplicitColumns]
public class ArticleCommentSchema
{
[PrimaryKeyColumn(AutoIncrement = true, IdentitySeed = 1)]
[Column("Id")]
public int Id { get; set; }
[Column("Comment")]
public string Comment { get; set; }
[Column("UmbracoPageId")]
public int UmbracoPageId { get; set; }
[Column("UserID")]
public string UserID { get; set; }
[Column("Created")]
public DateTimeOffset Created { get; set; }
[Column("Deleted")]
public bool Deleted { get; set; }
}
We define the table name, what the primary key is, and auto increment. Standard stuff.
Then we add the names of each column. Done.
Then we add the migration.
public class AddArticleCommentsTable : MigrationBase
{
private readonly ILogger logger;
public AddArticleCommentsTable(IMigrationContext context, ILogger logger) : base(context)
{
this.logger = logger;
}
public override void Migrate()
{
logger.Debug<AddArticleCommentsTable>("Running migration {MigrationStep}", "AddArticleCommentsTable");
// Lots of methods available in the MigrationBase class - discover with this.
if (TableExists("ArticleComments") == false)
{
Create.Table<ArticleCommentSchema>().Do();
}
else
{
logger.Debug<AddArticleCommentsTable>("The database table {DbTable} already exists, skipping", "ArticleComments");
}
}
}
It is fairly simple, it checks if the table exists, and if it doesn’t it creates it.
And lastly the component.
public class ArticleCommentMigrationComponent : IComponent
{
private readonly ILogger logger;
private readonly IScopeProvider scopeProvider;
private readonly IMigrationBuilder migrationBuilder;
private readonly IKeyValueService keyValueService;
public ArticleCommentMigrationComponent(ILogger logger, IScopeProvider scopeProvider, IMigrationBuilder migrationBuilder, IKeyValueService keyValueService)
{
this.logger = logger;
this.scopeProvider = scopeProvider;
this.migrationBuilder = migrationBuilder;
this.keyValueService = keyValueService;
}
public void Initialize()
{
// Create a migration plan for a specific project/feature
// We can then track that latest migration state/step for this project/feature
var commentsMigrationPlan = new MigrationPlan("ArticleComments");
// This is the steps we need to take
// Each step in the migration adds a unique value
commentsMigrationPlan.From(string.Empty)
.To<AddArticleCommentsTable>("Article-Comment-migration");
// Go and upgrade our site (Will check if it needs to do the work or not)
// Based on the current/latest step
var upgrader = new Upgrader(commentsMigrationPlan);
upgrader.Execute(scopeProvider, migrationBuilder, keyValueService, logger);
}
public void Terminate()
{
}
}
Here the migration is added to the Migration plan. “Article-Comment-migration” is the name of the migration and will be seen in the UmbracoKeyValues table, here it can be seen added below.
There are more resources available here:
https://www.zpqrtbnk.net/posts/migrations-in-v8