119 lines
4.4 KiB
C#
119 lines
4.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Knot.Contracts.Conversations.Application.Abstractions;
|
|
using Knot.Contracts.Conversations.Domain;
|
|
using Knot.Contracts.Conversations.Infrastructure.Persistence;
|
|
using Knot.Shared.Kernel;
|
|
using Knot.Shared.Kernel.Security;
|
|
using MediatR;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Diagnostics;
|
|
using DomainChat = Knot.Contracts.Conversations.Domain.Chat;
|
|
|
|
namespace Knot.Modules.Conversations.Infrastructure.Persistence;
|
|
|
|
public sealed class ChatsDbContext : DbContext, Knot.Contracts.Conversations.Application.Abstractions.IChatsUnitOfWork, Knot.Contracts.Conversations.Infrastructure.Persistence.IChatsDbContext
|
|
{
|
|
private readonly IMediator? _mediator;
|
|
private readonly IEncryptionService? _encryptionService;
|
|
|
|
public ChatsDbContext(DbContextOptions<ChatsDbContext> options)
|
|
: base(options)
|
|
{
|
|
}
|
|
|
|
public ChatsDbContext(DbContextOptions<ChatsDbContext> options, IMediator mediator, IEncryptionService encryptionService)
|
|
: this(options)
|
|
{
|
|
_mediator = mediator;
|
|
_encryptionService = encryptionService;
|
|
}
|
|
|
|
public DbSet<DomainChat> Chats => Set<DomainChat>();
|
|
public DbSet<Folder> Folders => Set<Folder>();
|
|
public DbSet<UserChatSettings> UserChatSettings => Set<UserChatSettings>();
|
|
|
|
IQueryable<Knot.Contracts.Conversations.Infrastructure.Persistence.Chat> Knot.Contracts.Conversations.Infrastructure.Persistence.IChatsDbContext.Chats =>
|
|
Set<DomainChat>().Select(c => new Knot.Contracts.Conversations.Infrastructure.Persistence.Chat { Id = c.Id, Avatar = c.Avatar });
|
|
|
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
|
{
|
|
base.OnConfiguring(optionsBuilder);
|
|
optionsBuilder.ConfigureWarnings(w => w.Ignore(RelationalEventId.PendingModelChangesWarning));
|
|
}
|
|
|
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
{
|
|
modelBuilder.HasDefaultSchema("chats");
|
|
|
|
modelBuilder.Entity<DomainChat>(builder =>
|
|
{
|
|
builder.ToTable("Chats");
|
|
builder.HasKey(c => c.Id);
|
|
builder.Property(c => c.IsImporting);
|
|
builder.Property(c => c.ImportJobId);
|
|
builder.Property(c => c.Type).HasConversion<string>();
|
|
|
|
builder.OwnsMany(c => c.Members, mb =>
|
|
{
|
|
mb.ToTable("ChatMembers");
|
|
mb.HasKey(m => m.Id);
|
|
mb.WithOwner().HasForeignKey(m => m.ChatId);
|
|
mb.HasIndex(m => new { m.ChatId, m.UserId }).IsUnique();
|
|
}).Navigation(c => c.Members).UsePropertyAccessMode(PropertyAccessMode.Field);
|
|
});
|
|
|
|
modelBuilder.Entity<Folder>(builder =>
|
|
{
|
|
builder.ToTable("Folders");
|
|
builder.HasKey(f => f.Id);
|
|
builder.Property(f => f.Type).HasConversion<string>();
|
|
});
|
|
|
|
modelBuilder.Entity<UserChatSettings>(builder =>
|
|
{
|
|
builder.ToTable("UserChatSettings");
|
|
builder.HasKey(s => s.Id);
|
|
builder.HasIndex(s => new { s.UserId, s.ChatId }).IsUnique();
|
|
|
|
builder.Property(s => s.FolderIds)
|
|
.HasConversion(
|
|
v => string.Join(',', v),
|
|
v => v.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(Guid.Parse).ToList()
|
|
);
|
|
});
|
|
}
|
|
|
|
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);
|
|
|
|
if (_mediator != null)
|
|
{
|
|
foreach (var domainEvent in domainEvents)
|
|
{
|
|
await _mediator.Publish(domainEvent, cancellationToken);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|