107 lines
3.6 KiB
C#
107 lines
3.6 KiB
C#
using MediatR;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Diagnostics;
|
|
using Vortex.Shared.Kernel;
|
|
using Vortex.Modules.Identity.Domain;
|
|
|
|
using Vortex.Modules.Identity.Application.Abstractions;
|
|
|
|
namespace Vortex.Modules.Identity.Infrastructure.Persistence;
|
|
|
|
/// <summary>
|
|
/// Контекст базы данных для модуля Identity.
|
|
/// </summary>
|
|
public sealed class IdentityDbContext : DbContext, IIdentityUnitOfWork
|
|
{
|
|
private readonly IMediator _mediator;
|
|
|
|
public IdentityDbContext(DbContextOptions<IdentityDbContext> options, IMediator mediator)
|
|
: base(options)
|
|
{
|
|
_mediator = mediator;
|
|
}
|
|
|
|
public DbSet<User> Users => Set<User>();
|
|
public DbSet<Story> Stories => Set<Story>();
|
|
public DbSet<StoryViewer> StoryViewers => Set<StoryViewer>();
|
|
public DbSet<Friendship> Friendships => Set<Friendship>();
|
|
|
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
|
{
|
|
base.OnConfiguring(optionsBuilder);
|
|
optionsBuilder.ConfigureWarnings(w => w.Ignore(RelationalEventId.PendingModelChangesWarning));
|
|
}
|
|
|
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
{
|
|
modelBuilder.HasDefaultSchema("identity");
|
|
|
|
modelBuilder.Entity<Friendship>(builder =>
|
|
{
|
|
builder.ToTable("Friendships");
|
|
builder.HasKey(f => f.Id);
|
|
builder.HasIndex(f => new { f.UserId, f.FriendId }).IsUnique();
|
|
});
|
|
|
|
modelBuilder.Entity<Story>(builder =>
|
|
{
|
|
builder.ToTable("Stories");
|
|
builder.HasKey(s => s.Id);
|
|
builder.Property(s => s.Type).IsRequired();
|
|
builder.HasMany(s => s.Viewers)
|
|
.WithOne()
|
|
.HasForeignKey(v => v.StoryId)
|
|
.OnDelete(DeleteBehavior.Cascade);
|
|
});
|
|
|
|
modelBuilder.Entity<StoryViewer>(builder =>
|
|
{
|
|
builder.ToTable("StoryViewers");
|
|
builder.HasKey(v => v.Id);
|
|
builder.HasIndex(v => new { v.StoryId, v.UserId }).IsUnique();
|
|
});
|
|
|
|
modelBuilder.Entity<User>(builder =>
|
|
{
|
|
builder.ToTable("Users");
|
|
builder.HasKey(u => u.Id);
|
|
builder.Property(u => u.Username).IsRequired().HasMaxLength(50);
|
|
builder.HasIndex(u => u.Username).IsUnique();
|
|
builder.Property(u => u.PasswordHash).IsRequired();
|
|
builder.Property(u => u.DisplayName).HasMaxLength(100);
|
|
builder.Property(u => u.Email).HasMaxLength(255);
|
|
builder.Property(u => u.Bio).HasMaxLength(500);
|
|
builder.Property(u => u.Avatar).HasMaxLength(500);
|
|
builder.Property(u => u.Birthday);
|
|
builder.Property(u => u.CreatedAt).IsRequired();
|
|
builder.Property(u => u.HideStoryViews).HasDefaultValue(false);
|
|
});
|
|
}
|
|
|
|
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
var domainEvents = ChangeTracker
|
|
.Entries<IAggregateRoot>()
|
|
.SelectMany(x =>
|
|
{
|
|
if (x.Entity is AggregateRoot<Guid> root)
|
|
{
|
|
var events = root.GetDomainEvents().ToList();
|
|
root.ClearDomainEvents();
|
|
return events;
|
|
}
|
|
return Enumerable.Empty<IDomainEvent>();
|
|
})
|
|
.ToList();
|
|
|
|
int result = await base.SaveChangesAsync(cancellationToken);
|
|
|
|
foreach (var domainEvent in domainEvents)
|
|
{
|
|
await _mediator.Publish(domainEvent, cancellationToken);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|