Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 62 additions & 16 deletions docs/02-Database.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,74 @@
### To change Database Provider

1. Update provider and connection string in the `appsettings.json`:
## To change Database Provider
Update provider and connection string in the `appsettings.json`:

#### SQLite
``` json
"Blogifier": {
"DbProvider": "Sqlite",
"ConnString": "Data Source=App_Data/blogifier.db",
...
}
```
It is recommended to put the database file under the App_Data folder. The logs and local pictures in the project will be stored in this path for persistence.

#### SqlServer
``` json
"Blogifier": {
"DbProvider": "SQLite",
"ConnString": "Data Source=Blog.db",
"DbProvider": "SqlServer",
"ConnString": "Data Source=mssql; User Id=sa; Password=Password; Initial Catalog=blogifier;TrustServerCertificate=True",
...
}
```
Valid providers: `SQLite`, `SqlServer`, `Postgres`, `MySql` (you'll need to supply valid connection string)
In the latest version of sql server connection, SqlClient will perform a secure connection by default, and you need to add a server certificate to the system. The example adds TrustServerCertificate=True to ignore this requirement. You can also delete this ignore and enable a secure connection.

2. Remove `Blogifier/Data/Migrations` folder with existing migrations
3. In the Visual Studio, open `Package Manager Console`, set `Blogifier`
as Default project and run these commands:
#### MySql
``` json
"Blogifier": {
"DbProvider": "MySql",
"ConnString": "server=mysql;user=root;password=password;database=blogifier",
...
}
```

#### Postgres
``` json
"Blogifier": {
"DbProvider": "Postgres",
"ConnString": "Host=postgres;Username=postgres;Password=password;Database=blogifier;",
...
}
```
Add-Migration Init -o Data\Migrations
Update-Database
In the above example, ConnString requires you to fill in the correct database host address username and password to connect normally


## When a change to an entity field requires a database migration

The database migration is stored in the src/Blogifier/Data/Migrations directory. The current project is still under development. When there is a modification, this directory may be deleted for quick migration. After the project is officially released, it is no longer recommended to delete the updated database migrate.

The following is the way to generate a new migration or delete the previous migration command. Before executing the command, please configure the corresponding DbProvider and ConnString in appsettings.json and then execute the corresponding migration command
``` shell
# Revert Migration Tool
dotnet tool restore

# Jump to project directory
cd src/Blogifier

# Sqlite
dotnet ef migrations add Init --context SqliteDbContext --output-dir Data/Migrations/Sqlite
dotnet ef migrations remove --context SqliteDbContext

# SqlServer
dotnet ef migrations add Init --context SqlServerDbContext --output-dir Data/Migrations/SqlServer
dotnet ef migrations remove --context SqlServerDbContext

# MySql
dotnet ef migrations add Init --context MySqlDbContext --output-dir Data/Migrations/MySql
dotnet ef migrations remove --context MySqlDbContext

# cil
dotnet ef migrations Init -o Data\Migrations
dotnet ef migrations remove
# Postgres
dotnet ef migrations add Init --context PostgresDbContext --output-dir Data/Migrations/Postgres
dotnet ef migrations remove --context MySqlDbContext
```

First command should re-generate provider specific code migrations and second will
execute them and create database specified in the connection string.
### Warn
Do not add or delete database migration at will. After the application generates data, random migration may cause data loss. This project will automatically apply the migration when it starts.
2 changes: 1 addition & 1 deletion src/Blogifier.Admin/Pages/Blogs/EditorView.razor
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
</svg>
<span class="ms-2 d-none d-lg-inline">@_localizer["delete"]</span>
</button>
<a href="/@Post.Slug" class="btn btn-link text-white" target="_blank">
<a href="/post/@Post.Slug" class="btn btn-link text-white" target="_blank">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-up-right" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M14 2.5a.5.5 0 0 0-.5-.5h-6a.5.5 0 0 0 0 1h4.793L2.146 13.146a.5.5 0 0 0 .708.708L13 3.707V8.5a.5.5 0 0 0 1 0v-6z" />
</svg>
Expand Down
37 changes: 15 additions & 22 deletions src/Blogifier/Data/AppDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,18 @@ namespace Blogifier.Data;

public class AppDbContext : IdentityUserContext<UserInfo, string>
{
protected readonly DbContextOptions<AppDbContext> _options;

public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
public AppDbContext(DbContextOptions options) : base(options)
{
_options = options;
}

}
public DbSet<OptionInfo> Options { get; set; } = default!;
public DbSet<Post> Posts { get; set; } = default!;
public DbSet<Storage> Storages { get; set; } = default!;
public DbSet<StorageReference> StorageReferences { get; set; } = default!;
public DbSet<Category> Categories { get; set; } = default!;
public DbSet<PostCategory> PostCategories { get; set; } = default!;
public DbSet<Subscriber> Subscribers { get; set; } = default!;
public DbSet<Newsletter> Newsletters { get; set; } = default!;
public DbSet<Subscriber> Subscribers { get; set; } = default!;
public DbSet<Storage> Storages { get; set; } = default!;
//public DbSet<StorageReference> StorageReferences { get; set; } = default!;

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
Expand All @@ -36,6 +33,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
e.ToTable("User");
e.Property(p => p.Id).HasMaxLength(128);
e.Property(p => p.CreatedAt).HasColumnOrder(0);
e.Property(p => p.UpdatedAt).HasColumnOrder(1);
e.Property(p => p.PasswordHash).HasMaxLength(256);
e.Property(p => p.SecurityStamp).HasMaxLength(32);
e.Property(p => p.ConcurrencyStamp).HasMaxLength(64);
Expand Down Expand Up @@ -65,27 +63,22 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
e.HasIndex(b => b.Key).IsUnique();
});

modelBuilder.Entity<StorageReference>(e =>
modelBuilder.Entity<Post>(e =>
{
e.ToTable("StorageReferences");
e.HasKey(t => new { t.StorageId, t.EntityId, t.Type });
e.ToTable("Post");
e.HasIndex(b => b.Slug).IsUnique();
});

//modelBuilder.Entity<StorageReference>(e =>
//{
// e.ToTable("StorageReferences");
// e.HasKey(t => new { t.StorageId, t.EntityId });
//});

modelBuilder.Entity<PostCategory>(e =>
{
e.ToTable("PostCategories");
e.HasKey(t => new { t.PostId, t.CategoryId });
});

modelBuilder.Entity<Post>(e =>
{
e.ToTable("Post");
e.HasIndex(b => b.Slug).IsUnique();

e.HasMany(e => e.StorageReferences)
.WithOne(e => e.Post)
.HasForeignKey(e => e.EntityId)
.IsRequired();
});
}
}
Loading