improvement: 태그 삭제 시 디바이스 orphan 참조 제거 (#186)
All checks were successful
SPMS_API/pipeline/head This commit looks good
All checks were successful
SPMS_API/pipeline/head This commit looks good
Reviewed-on: https://git.ipstein.myds.me/SPMS/SPMS_API/pulls/246
This commit is contained in:
commit
f474b916c4
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System.Text.Json;
|
||||||
using SPMS.Application.DTOs.Notice;
|
using SPMS.Application.DTOs.Notice;
|
||||||
using SPMS.Application.DTOs.Tag;
|
using SPMS.Application.DTOs.Tag;
|
||||||
using SPMS.Application.Interfaces;
|
using SPMS.Application.Interfaces;
|
||||||
|
|
@ -136,7 +137,30 @@ public class TagService : ITagService
|
||||||
if (tag == null)
|
if (tag == null)
|
||||||
throw new SpmsException(ErrorCodes.TagNotFound, "태그를 찾을 수 없습니다.", 404);
|
throw new SpmsException(ErrorCodes.TagNotFound, "태그를 찾을 수 없습니다.", 404);
|
||||||
|
|
||||||
|
// 트랜잭션으로 원자성 보장 (태그 삭제 + 디바이스 orphan 참조 제거)
|
||||||
|
using var tx = await _unitOfWork.BeginTransactionAsync();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 해당 태그를 참조하는 디바이스의 Tags에서 tagId 제거
|
||||||
|
var devices = await _deviceRepository.GetDevicesByTagIdAsync(request.TagId);
|
||||||
|
foreach (var device in devices)
|
||||||
|
{
|
||||||
|
var tagList = JsonSerializer.Deserialize<List<int>>(device.Tags!) ?? new();
|
||||||
|
tagList.Remove((int)request.TagId);
|
||||||
|
device.Tags = tagList.Count > 0 ? JsonSerializer.Serialize(tagList) : null;
|
||||||
|
device.UpdatedAt = DateTime.UtcNow;
|
||||||
|
_deviceRepository.Update(device);
|
||||||
|
}
|
||||||
|
|
||||||
_tagRepository.Delete(tag);
|
_tagRepository.Delete(tag);
|
||||||
|
|
||||||
await _unitOfWork.SaveChangesAsync();
|
await _unitOfWork.SaveChangesAsync();
|
||||||
|
await _unitOfWork.CommitTransactionAsync();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
await _unitOfWork.RollbackTransactionAsync();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,4 +20,5 @@ public interface IDeviceRepository : IRepository<Device>
|
||||||
bool? isActive = null, List<int>? tags = null,
|
bool? isActive = null, List<int>? tags = null,
|
||||||
string? keyword = null, bool? marketingAgreed = null);
|
string? keyword = null, bool? marketingAgreed = null);
|
||||||
Task<Dictionary<long, int>> GetDeviceCountsByTagIdsAsync(IEnumerable<long> tagIds);
|
Task<Dictionary<long, int>> GetDeviceCountsByTagIdsAsync(IEnumerable<long> tagIds);
|
||||||
|
Task<IReadOnlyList<Device>> GetDevicesByTagIdAsync(long tagId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,14 @@ public class DeviceRepository : Repository<Device>, IDeviceRepository
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IReadOnlyList<Device>> GetDevicesByTagIdAsync(long tagId)
|
||||||
|
{
|
||||||
|
var tagStr = tagId.ToString();
|
||||||
|
return await _dbSet
|
||||||
|
.Where(d => d.Tags != null && EF.Functions.Like(d.Tags, $"%{tagStr}%"))
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<Dictionary<long, int>> GetDeviceCountsByTagIdsAsync(IEnumerable<long> tagIds)
|
public async Task<Dictionary<long, int>> GetDeviceCountsByTagIdsAsync(IEnumerable<long> tagIds)
|
||||||
{
|
{
|
||||||
var tagIdList = tagIds.ToList();
|
var tagIdList = tagIds.ToList();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user