Files
forkmessager/apps/server-net/src/Modules/Identity/Infrastructure/Persistence/IdentityDbContext.cs
2026-03-12 22:54:15 +03:00

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;
}
}