// ToDo: More additional parameters which can be passed to the constructor of Thread/Post class
        public async Task <VBThread> CreateThreadAsync(VBUser author, string authorIpAddress, int forumId, string title, string text)
        {
            // We check the forum first so that no thread is created when Forum id doesn't exist
            var forum = db.Forums.Find(forumId);

            if (forum == null)
            {
                throw new Exception($"No forum with id #{forumId.ToString()} exists!");
            }

            var post = new VBPost(author, title, text, authorIpAddress);

            db.Posts.Add(post);
            await db.SaveChangesAsync();

            var thread = new VBThread(post.AuthorId.Value, post.AuthorName, post.Id, post.Id, forumId, post.AuthorId.Value, post.AuthorName, DateTime.Now, DateTime.Now, title);

            db.Threads.Add(thread);
            await db.SaveChangesAsync();

            post.ThreadId = thread.Id;
            await db.SaveChangesAsync();

            forum.LastPostId      = post.Id;
            forum.LastThreadId    = thread.Id;
            forum.LastThreadTitle = thread.Title;
            forum.PostCount++;
            forum.ThreadsCount++;
            forum.LastPostDate = DateTime.UtcNow;
            await db.SaveChangesAsync();

            await userManager.IncrementPostCounterAsync(author.Id, post.Id, post.CreatedTime);

            return(thread);
        }
        public async Task <VBPost> CreateReplyAsync(CreateReplyModel replyModel)
        {
            // Forum is required to generate view thread url after reply is saved
            var thread = await db.Threads.Include(t => t.Forum)
                         .FirstOrDefaultAsync(t => t.Id == replyModel.ThreadId);

            var post = new VBPost(replyModel.Author, replyModel.Title, replyModel.Text, replyModel.IpAddress, thread.Id);

            var lastPost = await db.Posts.Where(p => p.ThreadId == replyModel.ThreadId)
                           .OrderByDescending(p => p.CreatedTimeRaw)
                           .FirstOrDefaultAsync();

            if (lastPost != null)
            {
                post.ParentPostId = lastPost.Id;
            }

            db.Posts.Add(post);
            await db.SaveChangesAsync();

            if (post.Id <= 0)
            {
                throw new Exception("Couldnt save post: No id generated from database!");
            }

            thread.LastPostAuthorId   = replyModel.Author.Id;
            thread.LastPostAuthorName = replyModel.Author.UserName;
            thread.LastPostId         = post.Id;
            thread.LastPostTime       = DateTime.UtcNow;
            thread.ReplysCount++;
            // ToDo: Maybe also increment author counter if user hasn't posted before there

            bool userPostedInThread = await db.Posts.AnyAsync(p => p.ThreadId == thread.Id && p.AuthorId == replyModel.Author.Id);

            if (!userPostedInThread)
            {
                thread.PosterCount++;
            }

            await userManager.IncrementPostCounterAsync(replyModel.Author.Id, post.Id, post.CreatedTime);

            await db.SaveChangesAsync();

            cache.Remove(VBCacheKey.Thread, thread.Id.ToString());
            cache.Remove(VBCacheKey.ThreadReplys, thread.Id.ToString());
            post.Thread = thread;
            return(post);
        }