Modify database context and navigation

Creating a migration as-is creates an extraneous column. Need to figure
out what the problem is.
This commit is contained in:
Noi 2022-12-03 19:35:42 -08:00
parent b76d45a271
commit de7e83ee50
7 changed files with 24 additions and 17 deletions

View file

@ -54,6 +54,10 @@ public class BotDatabaseContext : DbContext {
modelBuilder.Entity<CachedGuildUser>(e => { modelBuilder.Entity<CachedGuildUser>(e => {
e.HasKey(p => new { p.GuildId, p.UserId }); e.HasKey(p => new { p.GuildId, p.UserId });
e.Property(p => p.FirstSeenTime).HasDefaultValueSql("now()"); e.Property(p => p.FirstSeenTime).HasDefaultValueSql("now()");
e.HasOne(entry => entry.User)
.WithMany(u => u.Guilds)
.HasForeignKey(entry => entry.UserId);
e.Navigation(entry => entry.User).AutoInclude();
}); });
modelBuilder.Entity<CachedGuildMessage>(e => e.Property(p => p.CreatedAt).HasDefaultValueSql("now()")); modelBuilder.Entity<CachedGuildMessage>(e => e.Property(p => p.CreatedAt).HasDefaultValueSql("now()"));
modelBuilder.HasPostgresEnum<ModLogType>(); modelBuilder.HasPostgresEnum<ModLogType>();
@ -62,6 +66,14 @@ public class BotDatabaseContext : DbContext {
e.HasOne(entry => entry.User) e.HasOne(entry => entry.User)
.WithMany(gu => gu.Logs) .WithMany(gu => gu.Logs)
.HasForeignKey(entry => new { entry.GuildId, entry.UserId }); .HasForeignKey(entry => new { entry.GuildId, entry.UserId });
e.Navigation(entry => entry.User).AutoInclude();
});
modelBuilder.Entity<CachedGuildMessage>(e => {
e.HasOne(entry => entry.Author)
.WithMany(gu => gu.Messages)
.HasForeignKey(cgm => new { cgm.GuildId, cgm.AuthorId })
.HasPrincipalKey(cgu => new { cgu.GuildId, cgu.UserId });
e.Navigation(entry => entry.Author).AutoInclude();
}); });
} }
} }

View file

@ -53,11 +53,8 @@ public class CachedGuildMessage {
/// </summary> /// </summary>
public string? Content { get; set; } = null!; public string? Content { get; set; } = null!;
/// <inheritdoc cref="CachedGuildUser.User" /> /// <inheritdoc cref="ModLogEntry.User"/>
[ForeignKey(nameof(AuthorId))] public CachedGuildUser Author { get; set; } = null!;
[InverseProperty(nameof(CachedUser.GuildMessages))]
public CachedUser Author { get; set; } = null!;
// TODO set up composite foreign key. will require rewriting some parts in modules...
// Used by MessageCachingSubservice // Used by MessageCachingSubservice
internal static CachedGuildMessage? Clone(CachedGuildMessage? original) { internal static CachedGuildMessage? Clone(CachedGuildMessage? original) {

View file

@ -28,14 +28,17 @@ public class CachedGuildUser {
public string? Nickname { get; set; } public string? Nickname { get; set; }
/// <summary> /// <summary>
/// If included in the query, references the associated <seealso cref="CachedUser"/> for this entry. /// Gets the associated <seealso cref="CachedUser"/> for this entry. This entity is auto-included.
/// </summary> /// </summary>
[ForeignKey(nameof(UserId))]
[InverseProperty(nameof(CachedUser.Guilds))]
public CachedUser User { get; set; } = null!; public CachedUser User { get; set; } = null!;
/// <summary> /// <summary>
/// If included in the query, references all <seealso cref="ModLogEntry"/> items associated with this entry. /// If included in the query, references all <seealso cref="ModLogEntry"/> items associated with this entry.
/// </summary> /// </summary>
public ICollection<ModLogEntry> Logs { get; set; } = null!; public ICollection<ModLogEntry> Logs { get; set; } = null!;
/// <summary>
/// If included in the query, references all <seealso cref="CachedGuildMessage"/> items associated with this entry.
/// </summary>
public ICollection<CachedGuildMessage> Messages { get; set; } = null!;
} }

View file

@ -37,12 +37,10 @@ public class CachedUser {
/// <summary> /// <summary>
/// If included in the query, gets the list of associated <seealso cref="CachedGuildUser"/> entries for this entry. /// If included in the query, gets the list of associated <seealso cref="CachedGuildUser"/> entries for this entry.
/// </summary> /// </summary>
[InverseProperty(nameof(CachedGuildUser.User))]
public ICollection<CachedGuildUser> Guilds { get; set; } = null!; public ICollection<CachedGuildUser> Guilds { get; set; } = null!;
/// <summary> /// <summary>
/// If included in the query, gets the list of associated <seealso cref="CachedGuildMessage"/> entries for this entry. /// If included in the query, gets the list of associated <seealso cref="CachedGuildMessage"/> entries for this entry.
/// </summary> /// </summary>
[InverseProperty(nameof(CachedGuildMessage.Author))]
public ICollection<CachedGuildMessage> GuildMessages { get; set; } = null!; public ICollection<CachedGuildMessage> GuildMessages { get; set; } = null!;
} }

View file

@ -44,7 +44,7 @@ public class ModLogEntry : ISharedEvent {
public string? Message { get; set; } public string? Message { get; set; }
/// <summary> /// <summary>
/// If included in the query, gets the associated <seealso cref="CachedGuildUser"/> for this entry. /// Gets the associated <seealso cref="CachedGuildUser"/> for this entry. This entity is auto-included.
/// </summary> /// </summary>
public CachedGuildUser User { get; set; } = null!; public CachedGuildUser User { get; set; } = null!;
} }

View file

@ -1,5 +1,4 @@
using Discord; using Discord;
using Microsoft.EntityFrameworkCore;
using RegexBot.Data; using RegexBot.Data;
using System.Text; using System.Text;
@ -24,7 +23,6 @@ internal partial class ModLogs {
using var db = new BotDatabaseContext(); using var db = new BotDatabaseContext();
var cachedMsg = db.GuildMessageCache var cachedMsg = db.GuildMessageCache
.Include(gm => gm.Author)
.Where(gm => gm.MessageId == argMsg.Id) .Where(gm => gm.MessageId == argMsg.Id)
.SingleOrDefault(); .SingleOrDefault();
@ -50,8 +48,8 @@ internal partial class ModLogs {
}; };
} else { } else {
reportEmbed.Author = new EmbedAuthorBuilder() { reportEmbed.Author = new EmbedAuthorBuilder() {
Name = $"{cachedMsg.Author.Username}#{cachedMsg.Author.Discriminator}", Name = $"{cachedMsg.Author.User.Username}#{cachedMsg.Author.User.Discriminator}",
IconUrl = cachedMsg.Author.AvatarUrl ?? GetDefaultAvatarUrl(cachedMsg.Author.Discriminator) IconUrl = cachedMsg.Author.User.AvatarUrl ?? GetDefaultAvatarUrl(cachedMsg.Author.User.Discriminator)
}; };
} }
SetAttachmentsField(reportEmbed, cachedMsg.AttachmentNames); SetAttachmentsField(reportEmbed, cachedMsg.AttachmentNames);

View file

@ -1,5 +1,4 @@
#pragma warning disable CA1822 // "Mark members as static" - members should only be callable by code with access to this instance #pragma warning disable CA1822 // "Mark members as static" - members should only be callable by code with access to this instance
using Microsoft.EntityFrameworkCore;
using RegexBot.Common; using RegexBot.Common;
using RegexBot.Data; using RegexBot.Data;
@ -112,7 +111,7 @@ class UserCachingSubservice {
internal CachedGuildUser? DoGuildUserQuery(ulong guildId, string search) { internal CachedGuildUser? DoGuildUserQuery(ulong guildId, string search) {
static CachedGuildUser? innerQuery(ulong guildId, ulong? sID, (string name, string? disc)? nameSearch) { static CachedGuildUser? innerQuery(ulong guildId, ulong? sID, (string name, string? disc)? nameSearch) {
var db = new BotDatabaseContext(); var db = new BotDatabaseContext();
var query = db.GuildUserCache.Include(gu => gu.User).Where(c => c.GuildId == guildId); var query = db.GuildUserCache.Where(c => c.GuildId == guildId);
if (sID.HasValue) if (sID.HasValue)
query = query.Where(c => c.UserId == sID.Value); query = query.Where(c => c.UserId == sID.Value);
if (nameSearch != null) { if (nameSearch != null) {