diff --git a/DbFirst.API/Controllers/CatalogsController.cs b/DbFirst.API/Controllers/CatalogsController.cs index 2d2bea9..d94cec4 100644 --- a/DbFirst.API/Controllers/CatalogsController.cs +++ b/DbFirst.API/Controllers/CatalogsController.cs @@ -50,6 +50,17 @@ public class CatalogsController : ControllerBase return NoContent(); } + [HttpPut("sp")] + public async Task> UpdateWithStoredProcedure(CatalogDto dto, CancellationToken cancellationToken) + { + var updated = await _service.UpdateWithStoredProcedureAsync(dto, cancellationToken); + if (updated == null) + { + return BadRequest(); + } + return Ok(updated); + } + [HttpDelete("{id:int}")] public async Task Delete(int id, CancellationToken cancellationToken) { @@ -60,4 +71,15 @@ public class CatalogsController : ControllerBase } return NoContent(); } + + [HttpDelete("sp/{id:int}")] + public async Task DeleteWithStoredProcedure(int id, CancellationToken cancellationToken) + { + var deleted = await _service.DeleteWithStoredProcedureAsync(id, cancellationToken); + if (!deleted) + { + return NotFound(); + } + return NoContent(); + } } diff --git a/DbFirst.Application/Catalogs/CatalogService.cs b/DbFirst.Application/Catalogs/CatalogService.cs index 4690387..52344f0 100644 --- a/DbFirst.Application/Catalogs/CatalogService.cs +++ b/DbFirst.Application/Catalogs/CatalogService.cs @@ -40,8 +40,20 @@ public class CatalogService : ICatalogService return await _repository.UpdateAsync(id, domainItem, cancellationToken); } + public async Task UpdateWithStoredProcedureAsync(CatalogDto dto, CancellationToken cancellationToken = default) + { + var domainItem = _mapper.Map(dto); + var updated = await _repository.UpdateWithStoredProcedureAsync(domainItem, cancellationToken); + return updated == null ? null : _mapper.Map(updated); + } + public async Task DeleteAsync(int id, CancellationToken cancellationToken = default) { return await _repository.DeleteAsync(id, cancellationToken); } + + public async Task DeleteWithStoredProcedureAsync(int id, CancellationToken cancellationToken = default) + { + return await _repository.DeleteWithStoredProcedureAsync(id, cancellationToken); + } } diff --git a/DbFirst.Application/Catalogs/ICatalogService.cs b/DbFirst.Application/Catalogs/ICatalogService.cs index 24101b0..a973fb5 100644 --- a/DbFirst.Application/Catalogs/ICatalogService.cs +++ b/DbFirst.Application/Catalogs/ICatalogService.cs @@ -6,5 +6,7 @@ public interface ICatalogService Task GetByIdAsync(int id, CancellationToken cancellationToken = default); Task CreateAsync(CatalogDto dto, CancellationToken cancellationToken = default); Task UpdateAsync(int id, CatalogDto dto, CancellationToken cancellationToken = default); + Task UpdateWithStoredProcedureAsync(CatalogDto dto, CancellationToken cancellationToken = default); Task DeleteAsync(int id, CancellationToken cancellationToken = default); + Task DeleteWithStoredProcedureAsync(int id, CancellationToken cancellationToken = default); } diff --git a/DbFirst.Domain/Repositories/ICatalogRepository.cs b/DbFirst.Domain/Repositories/ICatalogRepository.cs index 92e3dfd..a65b48d 100644 --- a/DbFirst.Domain/Repositories/ICatalogRepository.cs +++ b/DbFirst.Domain/Repositories/ICatalogRepository.cs @@ -8,5 +8,7 @@ public interface ICatalogRepository Task GetByIdAsync(int id, CancellationToken cancellationToken = default); Task AddAsync(Catalog catalog, CancellationToken cancellationToken = default); Task UpdateAsync(int id, Catalog catalog, CancellationToken cancellationToken = default); + Task UpdateWithStoredProcedureAsync(Catalog catalog, CancellationToken cancellationToken = default); Task DeleteAsync(int id, CancellationToken cancellationToken = default); + Task DeleteWithStoredProcedureAsync(int id, CancellationToken cancellationToken = default); } diff --git a/DbFirst.Infrastructure/DbFirst.Infrastructure.csproj b/DbFirst.Infrastructure/DbFirst.Infrastructure.csproj index e9c23bf..01e5904 100644 --- a/DbFirst.Infrastructure/DbFirst.Infrastructure.csproj +++ b/DbFirst.Infrastructure/DbFirst.Infrastructure.csproj @@ -14,6 +14,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/DbFirst.Infrastructure/Repositories/CatalogRepository.cs b/DbFirst.Infrastructure/Repositories/CatalogRepository.cs index f209804..7b66f0b 100644 --- a/DbFirst.Infrastructure/Repositories/CatalogRepository.cs +++ b/DbFirst.Infrastructure/Repositories/CatalogRepository.cs @@ -2,7 +2,9 @@ using AutoMapper; using DbFirst.Domain.DomainEntities; using DbFirst.Domain.Repositories; using DbFirst.Infrastructure.ScaffoldEntities; +using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; +using System.Data; namespace DbFirst.Infrastructure.Repositories; @@ -51,6 +53,35 @@ public class CatalogRepository : ICatalogRepository return true; } + public async Task UpdateWithStoredProcedureAsync(Catalog catalog, CancellationToken cancellationToken = default) + { + // ensure the record exists by CAT_TITLE to avoid insert behavior of the SP + var exists = await _db.TbmyCatalogs.AsNoTracking().AnyAsync(x => x.CatTitle == catalog.CatTitle, cancellationToken); + if (!exists) + { + return null; + } + + var catTitleParam = new SqlParameter("@CAT_TITLE", catalog.CatTitle); + var catStringParam = new SqlParameter("@CAT_STRING", catalog.CatString); + var changedWhoParam = new SqlParameter("@CHANGED_WHO", (object?)catalog.ChangedWho ?? DBNull.Value); + var guidOutParam = new SqlParameter("@GUID", SqlDbType.Int) { Direction = ParameterDirection.Output }; + + await _db.Database.ExecuteSqlRawAsync( + "EXEC dbo.PRTBMY_CATALOG_UPDATE @CAT_TITLE, @CAT_STRING, @CHANGED_WHO, @GUID OUTPUT", + parameters: new[] { catTitleParam, catStringParam, changedWhoParam, guidOutParam }, + cancellationToken: cancellationToken); + + if (guidOutParam.Value == DBNull.Value) + { + return null; + } + + var guid = (int)guidOutParam.Value; + var entity = await _db.TbmyCatalogs.AsNoTracking().FirstOrDefaultAsync(x => x.Guid == guid, cancellationToken); + return entity == null ? new Catalog { Guid = guid, CatTitle = catalog.CatTitle, CatString = catalog.CatString, ChangedWho = catalog.ChangedWho } : _mapper.Map(entity); + } + public async Task DeleteAsync(int id, CancellationToken cancellationToken = default) { var entity = await _db.TbmyCatalogs.FirstOrDefaultAsync(x => x.Guid == id, cancellationToken); @@ -63,4 +94,21 @@ public class CatalogRepository : ICatalogRepository await _db.SaveChangesAsync(cancellationToken); return true; } + + public async Task DeleteWithStoredProcedureAsync(int id, CancellationToken cancellationToken = default) + { + var exists = await _db.TbmyCatalogs.AsNoTracking().AnyAsync(x => x.Guid == id, cancellationToken); + if (!exists) + { + return false; + } + + var guidParam = new SqlParameter("@GUID", id); + await _db.Database.ExecuteSqlRawAsync( + "EXEC dbo.PRTBMY_CATALOG_DELETE @GUID", + parameters: new[] { guidParam }, + cancellationToken: cancellationToken); + + return true; + } }