Blog, Audit ve Forum AppService performans
This commit is contained in:
parent
ec44d03e79
commit
8014d9df34
4 changed files with 128 additions and 68 deletions
|
|
@ -1,11 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Volo.Abp;
|
using Volo.Abp;
|
||||||
using Volo.Abp.Application.Dtos;
|
using Volo.Abp.Application.Dtos;
|
||||||
using Volo.Abp.Application.Services;
|
using Volo.Abp.Application.Services;
|
||||||
using Volo.Abp.AuditLogging;
|
using Volo.Abp.AuditLogging;
|
||||||
|
using Volo.Abp.Uow;
|
||||||
using static Erp.Platform.Data.Seeds.SeedConsts;
|
using static Erp.Platform.Data.Seeds.SeedConsts;
|
||||||
|
|
||||||
namespace Erp.Platform.AuditLogs;
|
namespace Erp.Platform.AuditLogs;
|
||||||
|
|
@ -32,6 +34,7 @@ public class AuditLogAppService
|
||||||
return await MapToGetOutputDtoAsync(entity);
|
return await MapToGetOutputDtoAsync(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnitOfWork]
|
||||||
public override async Task<PagedResultDto<AuditLogDto>> GetListAsync(PagedAndSortedResultRequestDto input)
|
public override async Task<PagedResultDto<AuditLogDto>> GetListAsync(PagedAndSortedResultRequestDto input)
|
||||||
{
|
{
|
||||||
var query = await CreateFilteredQueryAsync(input);
|
var query = await CreateFilteredQueryAsync(input);
|
||||||
|
|
@ -41,14 +44,23 @@ public class AuditLogAppService
|
||||||
query = ApplySorting(query, input);
|
query = ApplySorting(query, input);
|
||||||
query = ApplyPaging(query, input);
|
query = ApplyPaging(query, input);
|
||||||
|
|
||||||
var auditLogList = await AsyncExecuter.ToListAsync(query);
|
// EntityChanges ile birlikte getir (N+1 query önlenir)
|
||||||
|
var auditLogRepository = (IAuditLogRepository)Repository;
|
||||||
|
var auditLogsWithDetails = await auditLogRepository.GetListAsync(
|
||||||
|
sorting: input.Sorting,
|
||||||
|
maxResultCount: input.MaxResultCount,
|
||||||
|
skipCount: input.SkipCount,
|
||||||
|
includeDetails: true
|
||||||
|
);
|
||||||
|
|
||||||
var entityDtos = new List<AuditLogDto>();
|
// Mapping tek seferde yap
|
||||||
foreach (var item in auditLogList)
|
var entityDtos = ObjectMapper.Map<List<AuditLog>, List<AuditLogDto>>(auditLogsWithDetails);
|
||||||
|
|
||||||
|
// EntityChangeCount'u doldur (artık EntityChanges yüklü)
|
||||||
|
foreach (var dto in entityDtos)
|
||||||
{
|
{
|
||||||
var dto = await MapToGetListOutputDtoAsync(item);
|
var auditLog = auditLogsWithDetails.FirstOrDefault(a => a.Id == dto.Id);
|
||||||
dto.EntityChangeCount = item.EntityChanges?.Count ?? 0; // null kontrolü artık burada güvenli
|
dto.EntityChangeCount = auditLog?.EntityChanges?.Count ?? 0;
|
||||||
entityDtos.Add(dto);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new PagedResultDto<AuditLogDto>(
|
return new PagedResultDto<AuditLogDto>(
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Erp.Platform.Entities;
|
using Erp.Platform.Entities;
|
||||||
using Erp.Platform.Localization;
|
using Erp.Platform.Localization;
|
||||||
|
|
@ -6,6 +7,7 @@ using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.Extensions.Localization;
|
using Microsoft.Extensions.Localization;
|
||||||
using Volo.Abp.Domain.Repositories;
|
using Volo.Abp.Domain.Repositories;
|
||||||
using Volo.Abp.Users;
|
using Volo.Abp.Users;
|
||||||
|
using Volo.Abp.Uow;
|
||||||
using static Erp.Platform.Data.Seeds.SeedConsts;
|
using static Erp.Platform.Data.Seeds.SeedConsts;
|
||||||
|
|
||||||
namespace Erp.Platform.Public;
|
namespace Erp.Platform.Public;
|
||||||
|
|
@ -56,14 +58,17 @@ public class BlogAppService : PlatformAppService, IBlogAppService
|
||||||
var post = await _postRepository.GetAsync(id);
|
var post = await _postRepository.GetAsync(id);
|
||||||
var dto = ObjectMapper.Map<BlogPost, BlogPostDto>(post);
|
var dto = ObjectMapper.Map<BlogPost, BlogPostDto>(post);
|
||||||
|
|
||||||
// Get category
|
// Category'yi getir (her zaman gerekli)
|
||||||
dto.Category = ObjectMapper.Map<BlogCategory, BlogCategoryDto>(
|
if (post.CategoryId != Guid.Empty)
|
||||||
await _categoryRepository.GetAsync(post.CategoryId)
|
{
|
||||||
);
|
var category = await _categoryRepository.GetAsync(post.CategoryId);
|
||||||
|
dto.Category = ObjectMapper.Map<BlogCategory, BlogCategoryDto>(category);
|
||||||
|
}
|
||||||
|
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnitOfWork]
|
||||||
public async Task<BlogPostDto> UpdatePostAsync(Guid id, CreateUpdateBlogPostDto input)
|
public async Task<BlogPostDto> UpdatePostAsync(Guid id, CreateUpdateBlogPostDto input)
|
||||||
{
|
{
|
||||||
var post = await _postRepository.GetAsync(id);
|
var post = await _postRepository.GetAsync(id);
|
||||||
|
|
@ -84,22 +89,37 @@ public class BlogAppService : PlatformAppService, IBlogAppService
|
||||||
|
|
||||||
if (post.CategoryId != input.CategoryId)
|
if (post.CategoryId != input.CategoryId)
|
||||||
{
|
{
|
||||||
var oldCategory = await _categoryRepository.GetAsync(post.CategoryId);
|
// Eski ve yeni category'leri tek sorguda çek (N+1 önleme)
|
||||||
oldCategory.DecrementPostCount();
|
var categoryIds = new[] { post.CategoryId, input.CategoryId };
|
||||||
await _categoryRepository.UpdateAsync(oldCategory);
|
var categories = await AsyncExecuter.ToListAsync(
|
||||||
|
(await _categoryRepository.GetQueryableAsync())
|
||||||
|
.Where(c => categoryIds.Contains(c.Id))
|
||||||
|
);
|
||||||
|
|
||||||
var newCategory = await _categoryRepository.GetAsync(input.CategoryId);
|
var oldCategory = categories.FirstOrDefault(c => c.Id == post.CategoryId);
|
||||||
|
var newCategory = categories.FirstOrDefault(c => c.Id == input.CategoryId);
|
||||||
|
|
||||||
|
if (oldCategory != null)
|
||||||
|
{
|
||||||
|
oldCategory.DecrementPostCount();
|
||||||
|
await _categoryRepository.UpdateAsync(oldCategory, autoSave: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newCategory != null)
|
||||||
|
{
|
||||||
newCategory.IncrementPostCount();
|
newCategory.IncrementPostCount();
|
||||||
await _categoryRepository.UpdateAsync(newCategory);
|
await _categoryRepository.UpdateAsync(newCategory, autoSave: false);
|
||||||
|
}
|
||||||
|
|
||||||
post.CategoryId = input.CategoryId;
|
post.CategoryId = input.CategoryId;
|
||||||
}
|
}
|
||||||
|
|
||||||
await _postRepository.UpdateAsync(post);
|
await _postRepository.UpdateAsync(post, autoSave: true);
|
||||||
|
|
||||||
return await GetPostAsync(post.Id); // ✅ DTO dönülüyor
|
return await GetPostAsync(post.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnitOfWork]
|
||||||
public async Task DeletePostAsync(Guid id)
|
public async Task DeletePostAsync(Guid id)
|
||||||
{
|
{
|
||||||
var post = await _postRepository.GetAsync(id);
|
var post = await _postRepository.GetAsync(id);
|
||||||
|
|
@ -113,9 +133,9 @@ public class BlogAppService : PlatformAppService, IBlogAppService
|
||||||
// Update category post count
|
// Update category post count
|
||||||
var category = await _categoryRepository.GetAsync(post.CategoryId);
|
var category = await _categoryRepository.GetAsync(post.CategoryId);
|
||||||
category.DecrementPostCount();
|
category.DecrementPostCount();
|
||||||
await _categoryRepository.UpdateAsync(category);
|
await _categoryRepository.UpdateAsync(category, autoSave: false);
|
||||||
|
|
||||||
await _postRepository.DeleteAsync(id);
|
await _postRepository.DeleteAsync(id, autoSave: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<BlogPostDto> PublishPostAsync(Guid id)
|
public async Task<BlogPostDto> PublishPostAsync(Guid id)
|
||||||
|
|
@ -169,7 +189,7 @@ public class BlogAppService : PlatformAppService, IBlogAppService
|
||||||
IsActive = input.IsActive
|
IsActive = input.IsActive
|
||||||
};
|
};
|
||||||
|
|
||||||
await _categoryRepository.InsertAsync(category);
|
await _categoryRepository.InsertAsync(category, autoSave: true);
|
||||||
|
|
||||||
return ObjectMapper.Map<BlogCategory, BlogCategoryDto>(category);
|
return ObjectMapper.Map<BlogCategory, BlogCategoryDto>(category);
|
||||||
}
|
}
|
||||||
|
|
@ -186,7 +206,7 @@ public class BlogAppService : PlatformAppService, IBlogAppService
|
||||||
category.DisplayOrder = input.DisplayOrder;
|
category.DisplayOrder = input.DisplayOrder;
|
||||||
category.IsActive = input.IsActive;
|
category.IsActive = input.IsActive;
|
||||||
|
|
||||||
await _categoryRepository.UpdateAsync(category);
|
await _categoryRepository.UpdateAsync(category, autoSave: true);
|
||||||
|
|
||||||
return ObjectMapper.Map<BlogCategory, BlogCategoryDto>(category);
|
return ObjectMapper.Map<BlogCategory, BlogCategoryDto>(category);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Erp.Platform.DynamicData;
|
using Erp.Platform.DynamicData;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ using Volo.Abp.Authorization;
|
||||||
using Volo.Abp.Domain.Entities;
|
using Volo.Abp.Domain.Entities;
|
||||||
using Volo.Abp.Domain.Repositories;
|
using Volo.Abp.Domain.Repositories;
|
||||||
using Volo.Abp.Identity;
|
using Volo.Abp.Identity;
|
||||||
|
using Volo.Abp.Uow;
|
||||||
|
|
||||||
namespace Erp.Platform.Forum;
|
namespace Erp.Platform.Forum;
|
||||||
|
|
||||||
|
|
@ -164,7 +165,7 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
await _categoryRepository.InsertAsync(category);
|
await _categoryRepository.InsertAsync(category, autoSave: true);
|
||||||
return ObjectMapper.Map<ForumCategory, ForumCategoryDto>(category);
|
return ObjectMapper.Map<ForumCategory, ForumCategoryDto>(category);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -181,7 +182,7 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
category.IsActive = input.IsActive;
|
category.IsActive = input.IsActive;
|
||||||
category.IsLocked = input.IsLocked;
|
category.IsLocked = input.IsLocked;
|
||||||
|
|
||||||
await _categoryRepository.UpdateAsync(category);
|
await _categoryRepository.UpdateAsync(category, autoSave: true);
|
||||||
return ObjectMapper.Map<ForumCategory, ForumCategoryDto>(category);
|
return ObjectMapper.Map<ForumCategory, ForumCategoryDto>(category);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,7 +192,7 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
var category = await _categoryRepository.GetAsync(id);
|
var category = await _categoryRepository.GetAsync(id);
|
||||||
category.IsLocked = !category.IsLocked;
|
category.IsLocked = !category.IsLocked;
|
||||||
|
|
||||||
await _categoryRepository.UpdateAsync(category);
|
await _categoryRepository.UpdateAsync(category, autoSave: true);
|
||||||
return ObjectMapper.Map<ForumCategory, ForumCategoryDto>(category);
|
return ObjectMapper.Map<ForumCategory, ForumCategoryDto>(category);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -201,19 +202,25 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
var category = await _categoryRepository.GetAsync(id);
|
var category = await _categoryRepository.GetAsync(id);
|
||||||
category.IsActive = !category.IsActive;
|
category.IsActive = !category.IsActive;
|
||||||
|
|
||||||
await _categoryRepository.UpdateAsync(category);
|
await _categoryRepository.UpdateAsync(category, autoSave: true);
|
||||||
return ObjectMapper.Map<ForumCategory, ForumCategoryDto>(category);
|
return ObjectMapper.Map<ForumCategory, ForumCategoryDto>(category);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize("App.ForumManagement.Delete")]
|
[Authorize("App.ForumManagement.Delete")]
|
||||||
|
[UnitOfWork]
|
||||||
public async Task DeleteCategoryAsync(Guid id)
|
public async Task DeleteCategoryAsync(Guid id)
|
||||||
{
|
{
|
||||||
// Delete all topics and posts in this category
|
// Tüm topic ID'lerini al
|
||||||
var topics = await _topicRepository.GetListAsync(t => t.CategoryId == id);
|
var topicQueryable = await _topicRepository.GetQueryableAsync();
|
||||||
var topicIds = topics.Select(t => t.Id).ToList();
|
var topicIds = await AsyncExecuter.ToListAsync(
|
||||||
|
topicQueryable
|
||||||
|
.Where(t => t.CategoryId == id)
|
||||||
|
.Select(t => t.Id)
|
||||||
|
);
|
||||||
|
|
||||||
if (topicIds.Any())
|
if (topicIds.Any())
|
||||||
{
|
{
|
||||||
|
// Bulk delete - daha performanslı
|
||||||
await _postRepository.DeleteAsync(p => topicIds.Contains(p.TopicId));
|
await _postRepository.DeleteAsync(p => topicIds.Contains(p.TopicId));
|
||||||
await _topicRepository.DeleteAsync(t => t.CategoryId == id);
|
await _topicRepository.DeleteAsync(t => t.CategoryId == id);
|
||||||
}
|
}
|
||||||
|
|
@ -267,12 +274,19 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
{
|
{
|
||||||
var topic = await _topicRepository.GetAsync(id);
|
var topic = await _topicRepository.GetAsync(id);
|
||||||
|
|
||||||
topic.ViewCount++;
|
// View count artırma işlemi arka planda yapılmalı (performans için)
|
||||||
await _topicRepository.UpdateAsync(topic);
|
// Her okumada update yapmak performans sorununa neden olur
|
||||||
|
_ = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
var t = await _topicRepository.GetAsync(id);
|
||||||
|
t.ViewCount++;
|
||||||
|
await _topicRepository.UpdateAsync(t);
|
||||||
|
});
|
||||||
|
|
||||||
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnitOfWork]
|
||||||
public async Task<ForumTopicDto> CreateTopicAsync(CreateForumTopicDto input)
|
public async Task<ForumTopicDto> CreateTopicAsync(CreateForumTopicDto input)
|
||||||
{
|
{
|
||||||
var topic = new ForumTopic(
|
var topic = new ForumTopic(
|
||||||
|
|
@ -289,12 +303,12 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
IsLocked = input.IsLocked
|
IsLocked = input.IsLocked
|
||||||
};
|
};
|
||||||
|
|
||||||
await _topicRepository.InsertAsync(topic);
|
await _topicRepository.InsertAsync(topic, autoSave: false);
|
||||||
|
|
||||||
// Update category topic count
|
// Update category topic count
|
||||||
var category = await _categoryRepository.GetAsync(input.CategoryId);
|
var category = await _categoryRepository.GetAsync(input.CategoryId);
|
||||||
category.TopicCount++;
|
category.TopicCount++;
|
||||||
await _categoryRepository.UpdateAsync(category);
|
await _categoryRepository.UpdateAsync(category, autoSave: true);
|
||||||
|
|
||||||
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
||||||
}
|
}
|
||||||
|
|
@ -309,25 +323,28 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
topic.IsLocked = input.IsLocked;
|
topic.IsLocked = input.IsLocked;
|
||||||
topic.IsSolved = input.IsSolved;
|
topic.IsSolved = input.IsSolved;
|
||||||
|
|
||||||
await _topicRepository.UpdateAsync(topic);
|
await _topicRepository.UpdateAsync(topic, autoSave: true);
|
||||||
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnitOfWork]
|
||||||
public async Task DeleteTopicAsync(Guid id)
|
public async Task DeleteTopicAsync(Guid id)
|
||||||
{
|
{
|
||||||
var topic = await _topicRepository.GetAsync(id);
|
var topic = await _topicRepository.GetAsync(id);
|
||||||
|
|
||||||
// Delete all posts in this topic
|
// Post sayısını al
|
||||||
|
var postCount = await _postRepository.CountAsync(p => p.TopicId == id);
|
||||||
|
|
||||||
|
// Tüm postları sil
|
||||||
await _postRepository.DeleteAsync(p => p.TopicId == id);
|
await _postRepository.DeleteAsync(p => p.TopicId == id);
|
||||||
|
|
||||||
// Update category counts
|
// Update category counts
|
||||||
var category = await _categoryRepository.GetAsync(topic.CategoryId);
|
var category = await _categoryRepository.GetAsync(topic.CategoryId);
|
||||||
category.TopicCount = Math.Max(0, category.TopicCount ?? 0 - 1);
|
category.TopicCount = Math.Max(0, (category.TopicCount ?? 0) - 1);
|
||||||
var postCount = await _postRepository.CountAsync(p => p.TopicId == id);
|
category.PostCount = Math.Max(0, (category.PostCount ?? 0) - postCount);
|
||||||
category.PostCount = Math.Max(0, category.PostCount ?? 0 - postCount);
|
await _categoryRepository.UpdateAsync(category, autoSave: false);
|
||||||
await _categoryRepository.UpdateAsync(category);
|
|
||||||
|
|
||||||
await _topicRepository.DeleteAsync(id);
|
await _topicRepository.DeleteAsync(id, autoSave: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post management
|
// Post management
|
||||||
|
|
@ -373,6 +390,7 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
return ObjectMapper.Map<ForumPost, ForumPostDto>(post);
|
return ObjectMapper.Map<ForumPost, ForumPostDto>(post);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnitOfWork]
|
||||||
public async Task<ForumPostDto> CreatePostAsync(CreateForumPostDto input)
|
public async Task<ForumPostDto> CreatePostAsync(CreateForumPostDto input)
|
||||||
{
|
{
|
||||||
var post = new ForumPost(
|
var post = new ForumPost(
|
||||||
|
|
@ -385,25 +403,25 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
input.TenantId
|
input.TenantId
|
||||||
);
|
);
|
||||||
|
|
||||||
await _postRepository.InsertAsync(post, autoSave: true);
|
await _postRepository.InsertAsync(post, autoSave: false);
|
||||||
|
|
||||||
// 🔽 Update topic
|
// Update topic
|
||||||
var topic = await _topicRepository.GetAsync(input.TopicId);
|
var topic = await _topicRepository.GetAsync(input.TopicId);
|
||||||
topic.ReplyCount++;
|
topic.ReplyCount++;
|
||||||
topic.LastPostId = post.Id;
|
topic.LastPostId = post.Id;
|
||||||
topic.LastPostDate = post.CreationTime;
|
topic.LastPostDate = post.CreationTime;
|
||||||
topic.LastPostUserId = post.AuthorId;
|
topic.LastPostUserId = post.AuthorId;
|
||||||
topic.LastPostUserName = post.AuthorName;
|
topic.LastPostUserName = post.AuthorName;
|
||||||
await _topicRepository.UpdateAsync(topic);
|
await _topicRepository.UpdateAsync(topic, autoSave: false);
|
||||||
|
|
||||||
// 🔽 Update category
|
// Update category
|
||||||
var category = await _categoryRepository.GetAsync(topic.CategoryId);
|
var category = await _categoryRepository.GetAsync(topic.CategoryId);
|
||||||
category.PostCount++;
|
category.PostCount++;
|
||||||
category.LastPostId = post.Id;
|
category.LastPostId = post.Id;
|
||||||
category.LastPostDate = post.CreationTime;
|
category.LastPostDate = post.CreationTime;
|
||||||
category.LastPostUserId = post.AuthorId;
|
category.LastPostUserId = post.AuthorId;
|
||||||
category.LastPostUserName = post.AuthorName;
|
category.LastPostUserName = post.AuthorName;
|
||||||
await _categoryRepository.UpdateAsync(category);
|
await _categoryRepository.UpdateAsync(category, autoSave: true);
|
||||||
|
|
||||||
return ObjectMapper.Map<ForumPost, ForumPostDto>(post);
|
return ObjectMapper.Map<ForumPost, ForumPostDto>(post);
|
||||||
}
|
}
|
||||||
|
|
@ -421,7 +439,7 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
post.Content = input.Content;
|
post.Content = input.Content;
|
||||||
post.IsAcceptedAnswer = input.IsAcceptedAnswer;
|
post.IsAcceptedAnswer = input.IsAcceptedAnswer;
|
||||||
|
|
||||||
await _postRepository.UpdateAsync(post);
|
await _postRepository.UpdateAsync(post, autoSave: true);
|
||||||
return ObjectMapper.Map<ForumPost, ForumPostDto>(post);
|
return ObjectMapper.Map<ForumPost, ForumPostDto>(post);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -475,34 +493,46 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
await _categoryRepository.UpdateAsync(category);
|
await _categoryRepository.UpdateAsync(category);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnitOfWork]
|
||||||
public async Task<ForumPostDto> LikePostAsync(Guid id)
|
public async Task<ForumPostDto> LikePostAsync(Guid id)
|
||||||
{
|
{
|
||||||
var post = await _postRepository.GetAsync(id);
|
var post = await _postRepository.GetAsync(id);
|
||||||
post.LikeCount++;
|
post.LikeCount++;
|
||||||
await _postRepository.UpdateAsync(post);
|
await _postRepository.UpdateAsync(post, autoSave: false);
|
||||||
|
|
||||||
var topic = await _topicRepository.GetAsync(post.TopicId);
|
var topic = await _topicRepository.GetAsync(post.TopicId);
|
||||||
var postsInTopic = await _postRepository.GetListAsync(p => p.TopicId == topic.Id);
|
|
||||||
|
|
||||||
topic.LikeCount = postsInTopic.Sum(p => p.LikeCount ?? 0);
|
// Topic'teki tüm postların toplam like'larını hesapla (optimizasyon)
|
||||||
await _topicRepository.UpdateAsync(topic);
|
var queryable = await _postRepository.GetQueryableAsync();
|
||||||
|
var totalLikes = await AsyncExecuter.SumAsync(
|
||||||
|
queryable.Where(p => p.TopicId == topic.Id),
|
||||||
|
p => p.LikeCount ?? 0
|
||||||
|
);
|
||||||
|
|
||||||
|
topic.LikeCount = totalLikes;
|
||||||
|
await _topicRepository.UpdateAsync(topic, autoSave: true);
|
||||||
|
|
||||||
return ObjectMapper.Map<ForumPost, ForumPostDto>(post);
|
return ObjectMapper.Map<ForumPost, ForumPostDto>(post);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnitOfWork]
|
||||||
public async Task<ForumPostDto> UnlikePostAsync(Guid id)
|
public async Task<ForumPostDto> UnlikePostAsync(Guid id)
|
||||||
{
|
{
|
||||||
var post = await _postRepository.GetAsync(id);
|
var post = await _postRepository.GetAsync(id);
|
||||||
post.LikeCount = Math.Max(0, post.LikeCount ?? 0 - 1);
|
post.LikeCount = Math.Max(0, (post.LikeCount ?? 0) - 1);
|
||||||
await _postRepository.UpdateAsync(post);
|
await _postRepository.UpdateAsync(post, autoSave: false);
|
||||||
|
|
||||||
// 🔽 Topic'in toplam beğeni sayısını güncelle
|
// Topic'in toplam beğeni sayısını güncelle (optimizasyon)
|
||||||
var topic = await _topicRepository.GetAsync(post.TopicId);
|
var topic = await _topicRepository.GetAsync(post.TopicId);
|
||||||
|
|
||||||
var postsInTopic = await _postRepository.GetListAsync(p => p.TopicId == topic.Id);
|
var queryable = await _postRepository.GetQueryableAsync();
|
||||||
topic.LikeCount = postsInTopic.Sum(p => p.LikeCount ?? 0);
|
var totalLikes = await AsyncExecuter.SumAsync(
|
||||||
|
queryable.Where(p => p.TopicId == topic.Id),
|
||||||
|
p => p.LikeCount ?? 0
|
||||||
|
);
|
||||||
|
topic.LikeCount = totalLikes;
|
||||||
|
|
||||||
await _topicRepository.UpdateAsync(topic);
|
await _topicRepository.UpdateAsync(topic, autoSave: true);
|
||||||
|
|
||||||
return ObjectMapper.Map<ForumPost, ForumPostDto>(post);
|
return ObjectMapper.Map<ForumPost, ForumPostDto>(post);
|
||||||
}
|
}
|
||||||
|
|
@ -512,7 +542,7 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
var post = await _postRepository.GetAsync(id);
|
var post = await _postRepository.GetAsync(id);
|
||||||
post.IsAcceptedAnswer = true;
|
post.IsAcceptedAnswer = true;
|
||||||
|
|
||||||
await _postRepository.UpdateAsync(post);
|
await _postRepository.UpdateAsync(post, autoSave: true);
|
||||||
|
|
||||||
return ObjectMapper.Map<ForumPost, ForumPostDto>(post);
|
return ObjectMapper.Map<ForumPost, ForumPostDto>(post);
|
||||||
}
|
}
|
||||||
|
|
@ -521,7 +551,7 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
{
|
{
|
||||||
var post = await _postRepository.GetAsync(id);
|
var post = await _postRepository.GetAsync(id);
|
||||||
post.IsAcceptedAnswer = false;
|
post.IsAcceptedAnswer = false;
|
||||||
await _postRepository.UpdateAsync(post);
|
await _postRepository.UpdateAsync(post, autoSave: true);
|
||||||
|
|
||||||
return ObjectMapper.Map<ForumPost, ForumPostDto>(post);
|
return ObjectMapper.Map<ForumPost, ForumPostDto>(post);
|
||||||
}
|
}
|
||||||
|
|
@ -532,7 +562,7 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
var topic = await _topicRepository.GetAsync(id);
|
var topic = await _topicRepository.GetAsync(id);
|
||||||
topic.LikeCount++;
|
topic.LikeCount++;
|
||||||
|
|
||||||
await _topicRepository.UpdateAsync(topic);
|
await _topicRepository.UpdateAsync(topic, autoSave: true);
|
||||||
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -541,7 +571,7 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
var topic = await _topicRepository.GetAsync(id);
|
var topic = await _topicRepository.GetAsync(id);
|
||||||
topic.LikeCount = Math.Max(0, topic.LikeCount - 1);
|
topic.LikeCount = Math.Max(0, topic.LikeCount - 1);
|
||||||
|
|
||||||
await _topicRepository.UpdateAsync(topic);
|
await _topicRepository.UpdateAsync(topic, autoSave: true);
|
||||||
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -550,7 +580,7 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
var topic = await _topicRepository.GetAsync(id);
|
var topic = await _topicRepository.GetAsync(id);
|
||||||
topic.IsPinned = true;
|
topic.IsPinned = true;
|
||||||
|
|
||||||
await _topicRepository.UpdateAsync(topic);
|
await _topicRepository.UpdateAsync(topic, autoSave: true);
|
||||||
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -558,7 +588,7 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
{
|
{
|
||||||
var topic = await _topicRepository.GetAsync(id);
|
var topic = await _topicRepository.GetAsync(id);
|
||||||
topic.IsPinned = false;
|
topic.IsPinned = false;
|
||||||
await _topicRepository.UpdateAsync(topic);
|
await _topicRepository.UpdateAsync(topic, autoSave: true);
|
||||||
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -567,7 +597,7 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
var topic = await _topicRepository.GetAsync(id);
|
var topic = await _topicRepository.GetAsync(id);
|
||||||
topic.IsLocked = true;
|
topic.IsLocked = true;
|
||||||
|
|
||||||
await _topicRepository.UpdateAsync(topic);
|
await _topicRepository.UpdateAsync(topic, autoSave: true);
|
||||||
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -575,7 +605,7 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
{
|
{
|
||||||
var topic = await _topicRepository.GetAsync(id);
|
var topic = await _topicRepository.GetAsync(id);
|
||||||
topic.IsLocked = false;
|
topic.IsLocked = false;
|
||||||
await _topicRepository.UpdateAsync(topic);
|
await _topicRepository.UpdateAsync(topic, autoSave: true);
|
||||||
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -584,7 +614,7 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
var topic = await _topicRepository.GetAsync(id);
|
var topic = await _topicRepository.GetAsync(id);
|
||||||
topic.IsSolved = true;
|
topic.IsSolved = true;
|
||||||
|
|
||||||
await _topicRepository.UpdateAsync(topic);
|
await _topicRepository.UpdateAsync(topic, autoSave: true);
|
||||||
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -593,7 +623,7 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
var topic = await _topicRepository.GetAsync(id);
|
var topic = await _topicRepository.GetAsync(id);
|
||||||
topic.IsSolved = false;
|
topic.IsSolved = false;
|
||||||
|
|
||||||
await _topicRepository.UpdateAsync(topic);
|
await _topicRepository.UpdateAsync(topic, autoSave: true);
|
||||||
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
return ObjectMapper.Map<ForumTopic, ForumTopicDto>(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -615,4 +645,3 @@ public class ForumAppService : PlatformAppService, IForumAppService
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue