From 82743e6471cdd4180f8bc66870ce98c4d4e46ecb Mon Sep 17 00:00:00 2001 From: Toaster Date: Mon, 12 Oct 2026 18:01:09 +0200 Subject: [PATCH 1/2] Update all DB methods to always compare entities by ID instead of reference (except grief reports) --- .../GameDatabaseContext.Activity.cs | 8 +-- .../GameDatabaseContext.Comments.cs | 8 +-- .../GameDatabaseContext.Levels.cs | 10 +-- .../GameDatabaseContext.Notifications.cs | 8 +-- .../GameDatabaseContext.Photos.cs | 4 +- .../GameDatabaseContext.Registration.cs | 4 +- .../GameDatabaseContext.Relations.cs | 66 +++++++++---------- .../GameDatabaseContext.Tokens.cs | 20 +++--- .../Models/Comments/GameLevelComment.cs | 3 +- .../Models/Comments/GameProfileComment.cs | 4 +- .../Models/Comments/IGameComment.cs | 2 + .../Models/Relations/ICommentRelation.cs | 2 + .../Models/Relations/LevelCommentRelation.cs | 5 +- .../Relations/ProfileCommentRelation.cs | 5 +- .../Models/Relations/RateLevelRelation.cs | 6 +- 15 files changed, 84 insertions(+), 71 deletions(-) diff --git a/Refresh.Database/GameDatabaseContext.Activity.cs b/Refresh.Database/GameDatabaseContext.Activity.cs index dde98dc74..a5beb26cf 100644 --- a/Refresh.Database/GameDatabaseContext.Activity.cs +++ b/Refresh.Database/GameDatabaseContext.Activity.cs @@ -111,11 +111,11 @@ public DatabaseActivityPage GetUserRecentActivity(ActivityQueryParameters parame List userFriends = this.GetUsersMutuals(parameters.User).Select(u => (ObjectId?)u.UserId).ToList(); query = query.Where(e => - e.User?.UserId == parameters.User.UserId || + e.UserId == parameters.User.UserId || e.StoredObjectId == parameters.User.UserId || - favouriteUsers.Contains(e.User?.UserId) || + favouriteUsers.Contains(e.UserId) || favouriteUsers.Contains(e.StoredObjectId) || - userFriends.Contains(e.User?.UserId) || + userFriends.Contains(e.UserId) || userFriends.Contains(e.StoredObjectId) || #if false // FIXME: double query this.GetLevelById(e.StoredSequentialId ?? int.MaxValue)?.Publisher?.UserId == parameters.User.UserId || @@ -146,7 +146,7 @@ public DatabaseActivityPage GetRecentActivityFromUser(ActivityQueryParameters pa Debug.Assert(parameters.User != null); IEnumerable events = this.GetEvents(parameters) - .Where(e => e.User?.UserId == parameters.User.UserId); + .Where(e => e.UserId == parameters.User.UserId); return GetRecentActivity(events, parameters); } diff --git a/Refresh.Database/GameDatabaseContext.Comments.cs b/Refresh.Database/GameDatabaseContext.Comments.cs index c2e3f402c..58f85ee2b 100644 --- a/Refresh.Database/GameDatabaseContext.Comments.cs +++ b/Refresh.Database/GameDatabaseContext.Comments.cs @@ -40,7 +40,7 @@ public GameProfileComment PostCommentToProfile(GameUser profile, GameUser author public DatabaseList GetProfileComments(GameUser profile, int count, int skip) => new(this.GameProfileCommentsIncluded - .Where(c => c.Profile == profile) + .Where(c => c.ProfileUserId == profile.UserId) .OrderByDescending(c => c.Timestamp), skip, count); [Pure] @@ -48,7 +48,7 @@ public DatabaseList GetProfileComments(GameUser profile, int public void DeleteProfileComment(GameProfileComment comment) { - Debug.Assert(comment.Profile != null); + comment.Profile ??= this.GetUserByObjectId(comment.ProfileUserId)!; this.WriteEnsuringStatistics(comment.Profile, () => { comment.Profile.Statistics!.CommentCount--; @@ -79,7 +79,7 @@ public GameLevelComment PostCommentToLevel(GameLevel level, GameUser author, str public DatabaseList GetLevelComments(GameLevel level, int count, int skip) => new(this.GameLevelCommentsIncluded - .Where(c => c.Level == level) + .Where(c => c.LevelId == level.LevelId) .OrderByDescending(c => c.Timestamp), skip, count); [Pure] @@ -87,7 +87,7 @@ public DatabaseList GetLevelComments(GameLevel level, int coun public void DeleteLevelComment(GameLevelComment comment) { - Debug.Assert(comment.Level != null); + comment.Level ??= this.GetLevelById(comment.LevelId)!; this.WriteEnsuringStatistics(comment.Level, () => { comment.Level.Statistics!.CommentCount--; diff --git a/Refresh.Database/GameDatabaseContext.Levels.cs b/Refresh.Database/GameDatabaseContext.Levels.cs index 1f60e0b5e..905f86f02 100644 --- a/Refresh.Database/GameDatabaseContext.Levels.cs +++ b/Refresh.Database/GameDatabaseContext.Levels.cs @@ -117,7 +117,7 @@ public GameLevel GetStoryLevelById(int id) public GameLevel UpdateLevelPublisher(GameLevel level, GameUser newAuthor) { - if (level.Publisher?.UserId == newAuthor.UserId) + if (level.PublisherUserId == newAuthor.UserId) return level; if (level.Publisher != null) @@ -310,7 +310,7 @@ public DatabaseList GetLevelsByUser(GameUser user, int count, int ski { levels = this.GetLevelsByGameVersion(levelFilterSettings.GameVersion) .FilterByLevelFilterSettings(accessor, levelFilterSettings) - .Where(l => l.Publisher == null); + .Where(l => l.PublisherUserId == null); } else if (user.Username == SystemUsers.UnknownUserName) { @@ -329,7 +329,7 @@ public DatabaseList GetLevelsByUser(GameUser user, int count, int ski { levels = this.GetLevelsByGameVersion(levelFilterSettings.GameVersion) .FilterByLevelFilterSettings(accessor, levelFilterSettings) - .Where(l => l.Publisher == user); + .Where(l => l.PublisherUserId == user.UserId); } return new(levels.OrderByDescending(l => l.UpdateDate), skip, count); @@ -519,11 +519,11 @@ public DatabaseList SearchForLevels(int count, int skip, GameUser? us public int GetTotalLevelsPublishedByUser(GameUser user) => this.GameLevels - .Count(r => r.Publisher == user); + .Count(r => r.PublisherUserId == user.UserId); public int GetTotalLevelsPublishedByUser(GameUser user, TokenGame game) => this.GameLevels - .Count(r => r.Publisher == user && r.GameVersion == game); + .Count(r => r.PublisherUserId == user.UserId && r.GameVersion == game); [Pure] public int GetTotalTeamPickCount(TokenGame game) => this.GameLevels.FilterByGameVersion(game).Count(l => l.DateTeamPicked != null); diff --git a/Refresh.Database/GameDatabaseContext.Notifications.cs b/Refresh.Database/GameDatabaseContext.Notifications.cs index 79e56aa1a..4a234cc9c 100644 --- a/Refresh.Database/GameDatabaseContext.Notifications.cs +++ b/Refresh.Database/GameDatabaseContext.Notifications.cs @@ -47,14 +47,14 @@ public void ClearLoginFailNotificationsForUser(GameUser user) { this.Write(() => { - this.GameNotifications.RemoveRange(n => n.User == user && n.Title == LoginFail); + this.GameNotifications.RemoveRange(n => n.UserId == user.UserId && n.Title == LoginFail); }); } [Pure] public int GetNotificationCountByUser(GameUser user) => this.GameNotifications - .Count(n => n.User == user); + .Count(n => n.UserId == user.UserId); [Pure] public DatabaseList GetNotificationsByUser(GameUser user, int count, int skip) @@ -65,13 +65,13 @@ public DatabaseList GetNotificationsByUser(GameUser user, int [Pure] public GameNotification? GetNotificationByUuid(GameUser user, ObjectId id) => this.GameNotifications - .FirstOrDefault(n => n.User == user && n.NotificationId == id); + .FirstOrDefault(n => n.UserId == user.UserId && n.NotificationId == id); public void DeleteNotificationsByUser(GameUser user) { this.Write(() => { - this.GameNotifications.RemoveRange(n => n.User == user); + this.GameNotifications.RemoveRange(n => n.UserId == user.UserId); }); } diff --git a/Refresh.Database/GameDatabaseContext.Photos.cs b/Refresh.Database/GameDatabaseContext.Photos.cs index 9874595df..1da58b43c 100644 --- a/Refresh.Database/GameDatabaseContext.Photos.cs +++ b/Refresh.Database/GameDatabaseContext.Photos.cs @@ -66,7 +66,7 @@ public GamePhoto UploadPhoto(IPhotoUpload photo, IEnumerable { level.Statistics!.PhotoInLevelCount++; - if (level.Publisher?.UserId == publisher.UserId) + if (level.PublisherUserId == publisher.UserId) { level.Statistics!.PhotoByPublisherCount++; } @@ -157,7 +157,7 @@ public void RemovePhoto(GamePhoto photo) this.WriteEnsuringStatistics(photo.Publisher, photo.Level, () => { photo.Level.Statistics!.PhotoInLevelCount--; - if (photo.Level.Publisher?.UserId == photo.PublisherId) + if (photo.Level.PublisherUserId == photo.PublisherId) { photo.Level.Statistics!.PhotoByPublisherCount--; } diff --git a/Refresh.Database/GameDatabaseContext.Registration.cs b/Refresh.Database/GameDatabaseContext.Registration.cs index 0df6fd181..a0bb45491 100644 --- a/Refresh.Database/GameDatabaseContext.Registration.cs +++ b/Refresh.Database/GameDatabaseContext.Registration.cs @@ -182,12 +182,12 @@ public void VerifyUserEmail(GameUser user) this.Write(() => { user.EmailAddressVerified = true; - this.EmailVerificationCodes.RemoveRange(c => c.User == user); + this.EmailVerificationCodes.RemoveRange(c => c.UserId == user.UserId); }); } public bool VerificationCodeMatches(GameUser user, string code) => - this.EmailVerificationCodes.Any(c => c.User == user && c.Code == code); + this.EmailVerificationCodes.Any(c => c.UserId == user.UserId && c.Code == code); public bool IsVerificationCodeExpired(EmailVerificationCode code) => code.ExpiryDate < this._time.Now; diff --git a/Refresh.Database/GameDatabaseContext.Relations.cs b/Refresh.Database/GameDatabaseContext.Relations.cs index 16dc718d8..b72a7695e 100644 --- a/Refresh.Database/GameDatabaseContext.Relations.cs +++ b/Refresh.Database/GameDatabaseContext.Relations.cs @@ -21,12 +21,12 @@ public partial class GameDatabaseContext // Relations [Pure] public bool IsLevelFavouritedByUser(GameLevel level, GameUser user) => this.FavouriteLevelRelations - .FirstOrDefault(r => r.Level == level && r.User == user) != null; + .FirstOrDefault(r => r.LevelId == level.LevelId && r.UserId == user.UserId) != null; [Pure] public DatabaseList GetLevelsFavouritedByUser(GameUser user, int count, int skip, LevelFilterSettings levelFilterSettings, GameUser? accessor) => new(this.FavouriteLevelRelationsIncluded - .Where(r => r.User == user) + .Where(r => r.UserId == user.UserId) .OrderByDescending(r => r.Timestamp) .AsEnumerableIfRealm() .Select(r => r.Level) @@ -35,7 +35,7 @@ public DatabaseList GetLevelsFavouritedByUser(GameUser user, int coun public int GetTotalLevelsFavouritedByUser(GameUser user) => this.FavouriteLevelRelations - .Count(r => r.User == user); + .Count(r => r.UserId == user.UserId); public bool FavouriteLevel(GameLevel level, GameUser user) { @@ -66,7 +66,7 @@ public bool FavouriteLevel(GameLevel level, GameUser user) public bool UnfavouriteLevel(GameLevel level, GameUser user) { FavouriteLevelRelation? relation = this.FavouriteLevelRelations - .FirstOrDefault(r => r.Level == level && r.User == user); + .FirstOrDefault(r => r.LevelId == level.LevelId && r.UserId == user.UserId); if (relation == null) return false; @@ -84,7 +84,7 @@ public bool UnfavouriteLevel(GameLevel level, GameUser user) } public int GetTotalFavouritesForLevel(GameLevel level, bool includingAuthor = true) => this.FavouriteLevelRelations - .Count(r => r.Level == level && (includingAuthor || r.User != level.Publisher)); + .Count(r => r.LevelId == level.LevelId && (includingAuthor || r.UserId != level.PublisherUserId)); #endregion @@ -98,7 +98,7 @@ public int GetTotalFavouritesForLevel(GameLevel level, bool includingAuthor = tr [Pure] public bool IsUserFavouritedByUser(GameUser userToFavourite, GameUser userFavouriting) => this.FavouriteUserRelations - .Any(r => r.UserToFavourite == userToFavourite && r.UserFavouriting == userFavouriting); + .Any(r => r.UserToFavouriteId == userToFavourite.UserId && r.UserFavouritingId == userFavouriting.UserId); [Pure] public bool AreUsersMutual(GameUser user1, GameUser user2) => @@ -116,14 +116,14 @@ public IEnumerable GetUsersMutuals(GameUser user) [Pure] public DatabaseList GetUsersFavouritedByUser(GameUser user, int skip, int count) => new(this.FavouriteUserRelationsIncluded - .Where(r => r.UserFavouriting == user) + .Where(r => r.UserFavouritingId == user.UserId) .OrderByDescending(r => r.Timestamp) .AsEnumerableIfRealm() .Select(r => r.UserToFavourite), skip, count); public int GetTotalUsersFavouritedByUser(GameUser user) => this.FavouriteUserRelations - .Count(r => r.UserFavouriting == user); + .Count(r => r.UserFavouritingId == user.UserId); public int GetTotalUsersFavouritingUser(GameUser user) => this.FavouriteUserRelations @@ -169,7 +169,7 @@ public bool FavouriteUser(GameUser userToFavourite, GameUser userFavouriting) public bool UnfavouriteUser(GameUser userToFavourite, GameUser userFavouriting) { FavouriteUserRelation? relation = this.FavouriteUserRelations - .FirstOrDefault(r => r.UserToFavourite == userToFavourite && r.UserFavouriting == userFavouriting); + .FirstOrDefault(r => r.UserToFavouriteId == userToFavourite.UserId && r.UserFavouritingId == userFavouriting.UserId); if (relation == null) return false; @@ -198,12 +198,12 @@ public bool UnfavouriteUser(GameUser userToFavourite, GameUser userFavouriting) [Pure] public bool IsLevelQueuedByUser(GameLevel level, GameUser user) => this.QueueLevelRelations - .FirstOrDefault(r => r.Level == level && r.User == user) != null; + .FirstOrDefault(r => r.LevelId == level.LevelId && r.UserId == user.UserId) != null; [Pure] public DatabaseList GetLevelsQueuedByUser(GameUser user, int count, int skip, LevelFilterSettings levelFilterSettings, GameUser? accessor) => new(this.QueueLevelRelationsIncluded - .Where(r => r.User == user) + .Where(r => r.UserId == user.UserId) .OrderByDescending(r => r.Timestamp) .AsEnumerableIfRealm() .Select(r => r.Level) @@ -213,7 +213,7 @@ public DatabaseList GetLevelsQueuedByUser(GameUser user, int count, i [Pure] public int GetTotalLevelsQueuedByUser(GameUser user) => this.QueueLevelRelations - .Count(r => r.User == user); + .Count(r => r.UserId == user.UserId); public bool QueueLevel(GameLevel level, GameUser user) { @@ -237,7 +237,7 @@ public bool QueueLevel(GameLevel level, GameUser user) public bool DequeueLevel(GameLevel level, GameUser user) { QueueLevelRelation? relation = this.QueueLevelRelations - .FirstOrDefault(r => r.Level == level && r.User == user); + .FirstOrDefault(r => r.LevelId == level.LevelId && r.UserId == user.UserId); if (relation == null) return false; @@ -257,7 +257,7 @@ public void ClearQueue(GameUser user) this.WriteEnsuringStatistics(user, () => { user.Statistics!.QueueCount = 0; - this.QueueLevelRelations.RemoveRange(r => r.User == user); + this.QueueLevelRelations.RemoveRange(r => r.UserId == user.UserId); }); } @@ -366,16 +366,16 @@ public int GetRawRatingForReview(GameReview review) => this.GameReviewsIncluded.FirstOrDefault(gameReview => gameReview.ReviewId == reviewId); public bool ReviewRatingExistsByUser(GameUser user, GameReview review) - => this.RateReviewRelations.Any(relation => relation.Review == review && relation.User == user); + => this.RateReviewRelations.Any(relation => relation.Review == review && relation.UserId == user.UserId); public RateReviewRelation? GetRateReviewRelationForReview(GameUser user, GameReview review) => this.RateReviewRelationsIncluded.FirstOrDefault(r => r.UserId == user.UserId && r.ReviewId == review.ReviewId); public bool ReviewRatingExists(GameUser user, GameReview review, RatingType rating) - => this.RateReviewRelations.Any(r => r.Review == review && r.User == user && r.RatingType == rating); + => this.RateReviewRelations.Any(r => r.Review == review && r.UserId == user.UserId && r.RatingType == rating); private RateLevelRelation? GetRateRelationByUser(GameLevel level, GameUser user) - => this.RateLevelRelationsIncluded.FirstOrDefault(r => r.User == user && r.Level == level); + => this.RateLevelRelationsIncluded.FirstOrDefault(r => r.UserId == user.UserId && r.LevelId == level.LevelId); /// /// Get a user's rating on a particular level. @@ -423,7 +423,7 @@ public bool RateLevel(GameLevel level, GameUser user, RatingType type) public int GetTotalRatingsForLevel(GameLevel level, RatingType type, bool includingAuthor = true) => this.RateLevelRelations.Count(r => - r.Level == level && + r.LevelId == level.LevelId && r.RatingType == type && (includingAuthor || r.User != level.Publisher)); @@ -549,20 +549,20 @@ public int GetTotalReviewsByUser(GameUser user) public GameReview? GetReviewByLevelAndUser(GameLevel level, GameUser user) { return this.GameReviewsIncluded - .Where(r => r.Level == level) + .Where(r => r.LevelId == level.LevelId) .AsEnumerableIfRealm() .FirstOrDefault(r => r.Publisher.UserId == user.UserId); } public DatabaseList GetReviewsForLevel(GameLevel level, int count, int skip) => new(this.GameReviewsIncluded - .Where(r => r.Level == level) + .Where(r => r.LevelId == level.LevelId) .AsEnumerable() // Sort reviews from most liked to most disliked .OrderByDescending(this.GetRawRatingForReview), skip, count); public int GetTotalReviewsForLevel(GameLevel level) - => this.GameReviews.Count(r => r.Level == level); + => this.GameReviews.Count(r => r.LevelId == level.LevelId); #endregion @@ -591,7 +591,7 @@ public void PlayLevel(GameLevel level, GameUser user, int count) }; UniquePlayLevelRelation? uniqueRelation = this.UniquePlayLevelRelations - .FirstOrDefault(r => r.Level == level && r.User == user); + .FirstOrDefault(r => r.LevelId == level.LevelId && r.UserId == user.UserId); this.WriteEnsuringStatistics(level, () => { @@ -619,13 +619,13 @@ public void PlayLevel(GameLevel level, GameUser user, int count) public bool HasUserPlayedLevel(GameLevel level, GameUser user) => this.UniquePlayLevelRelations - .FirstOrDefault(r => r.Level == level && r.User == user) != null; + .FirstOrDefault(r => r.LevelId == level.LevelId && r.UserId == user.UserId) != null; public IEnumerable GetAllPlaysForLevel(GameLevel level) => - this.PlayLevelRelationsIncluded.Where(r => r.Level == level); + this.PlayLevelRelationsIncluded.Where(r => r.LevelId == level.LevelId); public IEnumerable GetAllPlaysForLevelByUser(GameLevel level, GameUser user) => - this.PlayLevelRelationsIncluded.Where(r => r.Level == level && r.User == user); + this.PlayLevelRelationsIncluded.Where(r => r.LevelId == level.LevelId && r.UserId == user.UserId); public int GetTotalPlaysForLevel(GameLevel level) => this.GetAllPlaysForLevel(level).Sum(playLevelRelation => playLevelRelation.Count); @@ -634,10 +634,10 @@ public int GetTotalPlaysForLevelByUser(GameLevel level, GameUser user) => this.GetAllPlaysForLevelByUser(level, user).Sum(playLevelRelation => playLevelRelation.Count); public int GetTotalUniquePlaysForLevel(GameLevel level, bool includingAuthor = true) => - this.UniquePlayLevelRelations.Count(r => r.Level == level && (includingAuthor || r.User != level.Publisher)); + this.UniquePlayLevelRelations.Count(r => r.LevelId == level.LevelId && (includingAuthor || r.User != level.Publisher)); public int GetTotalCompletionsForLevel(GameLevel level) => - this.GameScores.Count(s => s.Level == level); + this.GameScores.Count(s => s.LevelId == level.LevelId); public int GetTotalCompletionsForLevelByUser(GameLevel level, GameUser user) => this.GameScores.Count(s => s.LevelId == level.LevelId && s.PublisherId == user.UserId); @@ -659,10 +659,10 @@ public int GetTotalCompletionsForLevelByUser(GameLevel level, GameUser user) => .Include(r => r.Comment.Level); private ProfileCommentRelation? GetProfileCommentRelationByUser(GameProfileComment comment, GameUser user) => this.ProfileCommentRelationsIncluded - .FirstOrDefault(r => r.Comment == comment && r.User == user); + .FirstOrDefault(r => r.CommentSequentialId == comment.SequentialId && r.UserId == user.UserId); private LevelCommentRelation? GetLevelCommentRelationByUser(GameLevelComment comment, GameUser user) => this.LevelCommentRelationsIncluded - .FirstOrDefault(r => r.Comment == comment && r.User == user); + .FirstOrDefault(r => r.CommentSequentialId == comment.SequentialId && r.UserId == user.UserId); /// /// Get a user's rating on a particular profile comment. @@ -687,16 +687,16 @@ public int GetTotalCompletionsForLevelByUser(GameLevel level, GameUser user) => => this.GetLevelCommentRelationByUser(comment, user)?.RatingType; public int GetTotalRatingsForProfileComment(GameProfileComment comment, RatingType type) => - this.ProfileCommentRelations.Count(r => r.Comment == comment && r.RatingType == type); + this.ProfileCommentRelations.Count(r => r.CommentSequentialId == comment.SequentialId && r.RatingType == type); public int GetTotalRatingsForLevelComment(GameLevelComment comment, RatingType type) => - this.LevelCommentRelations.Count(r => r.Comment == comment && r.RatingType == type); + this.LevelCommentRelations.Count(r => r.CommentSequentialId == comment.SequentialId && r.RatingType == type); private void RateComment(GameUser user, TComment comment, RatingType ratingType, DbSet list) where TComment : class, IGameComment where TCommentRelation : class, ICommentRelation, new() { - TCommentRelation? relation = list.FirstOrDefault(r => r.Comment == comment && r.User == user); + TCommentRelation? relation = list.FirstOrDefault(r => r.CommentSequentialId == comment.SequentialId && r.UserId == user.UserId); if (relation == null) { @@ -756,7 +756,7 @@ public void AddTagRelation(GameUser user, GameLevel level, Tag tag) this.Write(() => { // Remove any old tags from this user on this level - this.TagLevelRelations.RemoveRange(this.TagLevelRelations.Where(t => t.User == user && t.Level == level)); + this.TagLevelRelations.RemoveRange(this.TagLevelRelations.Where(t => t.UserId == user.UserId && t.LevelId == level.LevelId)); this.TagLevelRelations.Add(new TagLevelRelation { diff --git a/Refresh.Database/GameDatabaseContext.Tokens.cs b/Refresh.Database/GameDatabaseContext.Tokens.cs index 533c35c74..b1a8a72e7 100644 --- a/Refresh.Database/GameDatabaseContext.Tokens.cs +++ b/Refresh.Database/GameDatabaseContext.Tokens.cs @@ -134,7 +134,7 @@ public void RevokeAllTokensForUser(GameUser user) { this.Write(() => { - this.Tokens.RemoveRange(t => t.User == user); + this.Tokens.RemoveRange(t => t.UserId == user.UserId); }); } @@ -142,7 +142,7 @@ public void RevokeAllTokensForUser(GameUser user, TokenType type) { this.Write(() => { - this.Tokens.RemoveRange(t => t.User == user && t.TokenType == type); + this.Tokens.RemoveRange(t => t.UserId == user.UserId && t.TokenType == type); }); } @@ -181,7 +181,7 @@ public void AddVerifiedIp(GameUser user, string ipAddress, IDateTimeProvider tim { const int maxVerifiedIps = 3; - int count = this.GameUserVerifiedIpRelations.Count(r => r.User == user); + int count = this.GameUserVerifiedIpRelations.Count(r => r.UserId == user.UserId); int toRemove = count >= maxVerifiedIps ? count - maxVerifiedIps + 1 : 0; this.Write(() => @@ -190,7 +190,7 @@ public void AddVerifiedIp(GameUser user, string ipAddress, IDateTimeProvider tim if (toRemove > 0) this.GameUserVerifiedIpRelations.RemoveRange( this.GameUserVerifiedIpRelations - .Where(r => r.User == user) + .Where(r => r.UserId == user.UserId) .OrderBy(r => r.VerifiedAt) .AsEnumerable() .Take(toRemove)); @@ -202,14 +202,14 @@ public void AddVerifiedIp(GameUser user, string ipAddress, IDateTimeProvider tim VerifiedAt = timeProvider.Now, }); - this.GameIpVerificationRequests.RemoveRange(r => r.User == user && r.IpAddress == ipAddress); + this.GameIpVerificationRequests.RemoveRange(r => r.UserId == user.UserId && r.IpAddress == ipAddress); }); } public bool RemoveVerifiedIp(GameUser user, string ipAddress) { GameUserVerifiedIpRelation? verifiedIp = - this.GameUserVerifiedIpRelations.FirstOrDefault(r => r.User == user && r.IpAddress == ipAddress); + this.GameUserVerifiedIpRelations.FirstOrDefault(r => r.UserId == user.UserId && r.IpAddress == ipAddress); if (verifiedIp == null) return false; @@ -223,16 +223,16 @@ public bool RemoveVerifiedIp(GameUser user, string ipAddress) } public DatabaseList GetVerifiedIps(GameUser user, int skip, int count) - => new(this.GameUserVerifiedIpRelations.Where(r => r.User == user), skip, count); + => new(this.GameUserVerifiedIpRelations.Where(r => r.UserId == user.UserId), skip, count); public bool IsIpVerified(GameUser user, string ipAddress) - => this.GameUserVerifiedIpRelations.Any(r => r.User == user && r.IpAddress == ipAddress); + => this.GameUserVerifiedIpRelations.Any(r => r.UserId == user.UserId && r.IpAddress == ipAddress); public void DenyIpVerificationRequest(GameUser user, string ipAddress) { this.Write(() => { - this.GameIpVerificationRequests.RemoveRange(r => r.IpAddress == ipAddress && r.User == user); + this.GameIpVerificationRequests.RemoveRange(r => r.IpAddress == ipAddress && r.UserId == user.UserId); }); } @@ -246,5 +246,5 @@ public void SetTokenDigestInfo(Token token, string digest, bool isHmacDigest) } public DatabaseList GetIpVerificationRequestsForUser(GameUser user, int count, int skip) - => new(this.GameIpVerificationRequests.Where(r => r.User == user), skip, count); + => new(this.GameIpVerificationRequests.Where(r => r.UserId == user.UserId), skip, count); } \ No newline at end of file diff --git a/Refresh.Database/Models/Comments/GameLevelComment.cs b/Refresh.Database/Models/Comments/GameLevelComment.cs index 74137e45f..3aa334c96 100644 --- a/Refresh.Database/Models/Comments/GameLevelComment.cs +++ b/Refresh.Database/Models/Comments/GameLevelComment.cs @@ -17,8 +17,9 @@ public partial class GameLevelComment : IGameComment, ISequentialId /// /// The destination level this comment was posted to. /// - [Required] + [Required, ForeignKey(nameof(LevelId))] public GameLevel Level { get; set; } = null!; + [Required] public int LevelId { get; set; } /// public string Content { get; set; } = string.Empty; diff --git a/Refresh.Database/Models/Comments/GameProfileComment.cs b/Refresh.Database/Models/Comments/GameProfileComment.cs index 72adb314a..858c4272f 100644 --- a/Refresh.Database/Models/Comments/GameProfileComment.cs +++ b/Refresh.Database/Models/Comments/GameProfileComment.cs @@ -16,8 +16,8 @@ public partial class GameProfileComment : IGameComment, ISequentialId /// /// The destination profile this comment was posted to. /// - [Required] - public GameUser Profile { get; set; } = null!; + [Required, ForeignKey(nameof(ProfileUserId))] public GameUser Profile { get; set; } = null!; + [Required] public ObjectId ProfileUserId { get; set; } /// public string Content { get; set; } = string.Empty; diff --git a/Refresh.Database/Models/Comments/IGameComment.cs b/Refresh.Database/Models/Comments/IGameComment.cs index ee6826578..3723f38d2 100644 --- a/Refresh.Database/Models/Comments/IGameComment.cs +++ b/Refresh.Database/Models/Comments/IGameComment.cs @@ -1,3 +1,4 @@ +using MongoDB.Bson; using Refresh.Database.Models.Users; namespace Refresh.Database.Models.Comments; @@ -10,6 +11,7 @@ public interface IGameComment /// The user who originally posted the comment. /// GameUser Author { get; set; } + ObjectId AuthorUserId { get; set; } /// /// The text content of the comment. diff --git a/Refresh.Database/Models/Relations/ICommentRelation.cs b/Refresh.Database/Models/Relations/ICommentRelation.cs index 79e4421a1..9d13c0d39 100644 --- a/Refresh.Database/Models/Relations/ICommentRelation.cs +++ b/Refresh.Database/Models/Relations/ICommentRelation.cs @@ -8,7 +8,9 @@ public interface ICommentRelation where TComment : IGameComment { ObjectId CommentRelationId { get; set; } [Required] GameUser User { get; set; } + [Required] ObjectId UserId { get; set; } [Required] TComment Comment { get; set; } + [Required] int CommentSequentialId { get; set; } RatingType RatingType { get; set; } DateTimeOffset Timestamp { get; set; } } \ No newline at end of file diff --git a/Refresh.Database/Models/Relations/LevelCommentRelation.cs b/Refresh.Database/Models/Relations/LevelCommentRelation.cs index 4e0c9b0f4..710c3d4b7 100644 --- a/Refresh.Database/Models/Relations/LevelCommentRelation.cs +++ b/Refresh.Database/Models/Relations/LevelCommentRelation.cs @@ -14,7 +14,10 @@ public partial class LevelCommentRelation : ICommentRelation public GameUser User { get; set; } [Required] public ObjectId UserId { get; set; } - [Required] public GameLevelComment Comment { get; set; } + [Required, ForeignKey(nameof(CommentSequentialId))] + public GameLevelComment Comment { get; set; } + [Required] public int CommentSequentialId { get; set; } + public RatingType RatingType { get; set; } public DateTimeOffset Timestamp { get; set; } } \ No newline at end of file diff --git a/Refresh.Database/Models/Relations/ProfileCommentRelation.cs b/Refresh.Database/Models/Relations/ProfileCommentRelation.cs index 38d057f2b..0a2425bc0 100644 --- a/Refresh.Database/Models/Relations/ProfileCommentRelation.cs +++ b/Refresh.Database/Models/Relations/ProfileCommentRelation.cs @@ -14,7 +14,10 @@ public partial class ProfileCommentRelation : ICommentRelation Date: Mon, 12 Oct 2026 18:14:05 +0200 Subject: [PATCH 2/2] Missed a few FKs on reviews/comments --- .../GameDatabaseContext.Relations.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Refresh.Database/GameDatabaseContext.Relations.cs b/Refresh.Database/GameDatabaseContext.Relations.cs index b72a7695e..c455f77e5 100644 --- a/Refresh.Database/GameDatabaseContext.Relations.cs +++ b/Refresh.Database/GameDatabaseContext.Relations.cs @@ -54,7 +54,7 @@ public bool FavouriteLevel(GameLevel level, GameUser user) level.Statistics!.FavouriteCount++; user.Statistics!.FavouriteLevelCount++; - if (level.Publisher == user) + if (level.PublisherUserId == user.UserId) level.Statistics!.FavouriteCountExcludingPublisher++; }); @@ -76,7 +76,7 @@ public bool UnfavouriteLevel(GameLevel level, GameUser user) level.Statistics!.FavouriteCount--; user.Statistics!.FavouriteLevelCount--; - if (level.Publisher == user) + if (level.PublisherUserId == user.UserId) level.Statistics!.FavouriteCountExcludingPublisher--; }); @@ -329,7 +329,7 @@ public void RateReview(GameReview review, RatingType ratingType, GameUser user) public DatabaseRating GetRatingForReview(GameReview review) { - IEnumerable relations = this.RateReviewRelations.Where(r => r.Review == review); + IEnumerable relations = this.RateReviewRelations.Where(r => r.ReviewId == review.ReviewId); DatabaseRating rating = new(); foreach (RateReviewRelation relation in relations) @@ -345,7 +345,7 @@ public DatabaseRating GetRatingForReview(GameReview review) public int GetRawRatingForReview(GameReview review) { - IQueryable relations = this.RateReviewRelations.Where(r => r.Review == review); + IQueryable relations = this.RateReviewRelations.Where(r => r.ReviewId == review.ReviewId); int rawRating = 0; foreach (RateReviewRelation relation in relations) @@ -366,13 +366,13 @@ public int GetRawRatingForReview(GameReview review) => this.GameReviewsIncluded.FirstOrDefault(gameReview => gameReview.ReviewId == reviewId); public bool ReviewRatingExistsByUser(GameUser user, GameReview review) - => this.RateReviewRelations.Any(relation => relation.Review == review && relation.UserId == user.UserId); + => this.RateReviewRelations.Any(relation => relation.ReviewId == review.ReviewId && relation.UserId == user.UserId); public RateReviewRelation? GetRateReviewRelationForReview(GameUser user, GameReview review) => this.RateReviewRelationsIncluded.FirstOrDefault(r => r.UserId == user.UserId && r.ReviewId == review.ReviewId); public bool ReviewRatingExists(GameUser user, GameReview review, RatingType rating) - => this.RateReviewRelations.Any(r => r.Review == review && r.UserId == user.UserId && r.RatingType == rating); + => this.RateReviewRelations.Any(r => r.ReviewId == review.ReviewId && r.UserId == user.UserId && r.RatingType == rating); private RateLevelRelation? GetRateRelationByUser(GameLevel level, GameUser user) => this.RateLevelRelationsIncluded.FirstOrDefault(r => r.UserId == user.UserId && r.LevelId == level.LevelId); @@ -485,7 +485,7 @@ public void DeleteReviewsPostedByUser(GameUser user) .Include(r => r.Level.Statistics) .Include(r => r.Publisher) .Include(r => r.Publisher.Statistics) - .Where(s => s.Publisher == user) + .Where(s => s.PublisherUserId == user.UserId) .ToList(); foreach (GameReview review in reviews) @@ -516,7 +516,7 @@ public void DeleteProfileCommentsPostedByUser(GameUser user) { IEnumerable comments = this.GameProfileComments .Include(c => c.Profile.Statistics) - .Where(c => c.Author == user) + .Where(c => c.AuthorUserId == user.UserId) .ToList(); foreach (GameProfileComment comment in comments) @@ -529,7 +529,7 @@ public void DeleteLevelCommentsPostedByUser(GameUser user) { IEnumerable comments = this.GameLevelComments .Include(c => c.Level.Statistics) - .Where(c => c.Author == user) + .Where(c => c.AuthorUserId == user.UserId) .ToList(); foreach (GameLevelComment comment in comments) @@ -540,11 +540,11 @@ public void DeleteLevelCommentsPostedByUser(GameUser user) public DatabaseList GetReviewsByUser(GameUser user, int count, int skip) => new(this.GameReviewsIncluded - .Where(r => r.Publisher == user) + .Where(r => r.PublisherUserId == user.UserId) .OrderByDescending(r => r.PostedAt), skip, count); public int GetTotalReviewsByUser(GameUser user) - => this.GameReviews.Count(r => r.Publisher == user); + => this.GameReviews.Count(r => r.PublisherUserId == user.UserId); public GameReview? GetReviewByLevelAndUser(GameLevel level, GameUser user) {