modules/backend/Write-Persistence-Hybrid.ps1
|
param( [string]$ProjectName, [string]$OrmMode, [string]$DbProvider, [string]$OutputPath, [string[]]$Entities ) if ($OrmMode -ne "Hybrid") { return } . (Join-Path (Split-Path $MyInvocation.MyCommand.Path) "..\core\Utils.ps1") $base = Join-Path $OutputPath "src\$ProjectName.Persistence" function Write-File($rel, $con) { Write-CoreFile (Join-Path $base $rel) $con } function T($template, $e = "") { $res = $template.Replace("{P}", $ProjectName) if ($e) { $res = $res.Replace("{E}", $e) } return $res } function Get-PagedSql { param($table, $cols) switch ($DbProvider) { "Postgres" { "SELECT $cols FROM $table WHERE IsDeleted=@IsDeleted ORDER BY Id LIMIT @Size OFFSET @Offset" } default { "SELECT $cols FROM $table WHERE IsDeleted=@IsDeleted ORDER BY Id OFFSET @Offset ROWS FETCH NEXT @Size ROWS ONLY" } } } foreach ($e in $Entities) { $pE = Get-Plural $e if ($e -eq "User") { # UserRepository in Hybrid Mode: Write -> EF Core, Read -> Dapper Write-File "Repositories\UserRepository.cs" (T @" using System.Data; using Dapper; using {P}.Domain.Entities; using {P}.Domain.Interfaces; using {P}.Persistence.Context; namespace {P}.Persistence.Repositories; public class UserRepository : IUserRepository { private readonly AppDbContext _ctx; private readonly IDbConnection _conn; public UserRepository(AppDbContext ctx, IDbConnection conn) { _ctx = ctx; _conn = conn; } public async Task<User?> GetByUsernameAsync(string u) => await _conn.QueryFirstOrDefaultAsync<User>( "SELECT Id, Username, PasswordHash, Email, IsActive, Role, CreatedAt, UpdatedAt, IsDeleted FROM Users WHERE Username=@u", new { u }); public async Task<int> AddAsync(User u) { await _ctx.Users.AddAsync(u); await _ctx.SaveChangesAsync(); return u.Id; } } "@) } else { # Generic Repository in Hybrid Mode: Write -> EF Core, Read -> Dapper (High Performance CQRS) $p = if ($e -eq "Product") { ", Price" } else { "" } $cols = "Id, Name$p, CreatedAt, UpdatedAt, IsDeleted" $pagedSql = Get-PagedSql $pE $cols Write-File "Repositories\$e`Repository.cs" (T @' using System.Data; using Dapper; using {P}.Domain.Common; using {P}.Domain.Entities; using {P}.Domain.Interfaces; using {P}.Persistence.Context; namespace {P}.Persistence.Repositories; public class {E}Repository : I{E}Repository { private readonly AppDbContext _ctx; private readonly IDbConnection _conn; public {E}Repository(AppDbContext ctx, IDbConnection conn) { _ctx = ctx; _conn = conn; } public async Task<{E}?> GetByIdAsync(int id) => await _conn.QueryFirstOrDefaultAsync<{E}>( "SELECT {Cols} FROM {PE} WHERE Id=@id AND IsDeleted=@IsDeleted", new { id, IsDeleted = false }); public async Task<IEnumerable<{E}>> GetAllAsync() => await _conn.QueryAsync<{E}>( "SELECT {Cols} FROM {PE} WHERE IsDeleted=@IsDeleted", new { IsDeleted = false }); public async Task<PagedResult<{E}>> GetPagedAsync(PagedQuery query) { var total = await _conn.ExecuteScalarAsync<int>( "SELECT COUNT(*) FROM {PE} WHERE IsDeleted=@IsDeleted", new { IsDeleted = false }); var items = await _conn.QueryAsync<{E}>( BTICK{PagedSql}BTICK, new { Offset = query.Skip, query.Size, IsDeleted = false }); return new PagedResult<{E}> { Items = items, TotalCount = total, Page = query.Page, Size = query.Size }; } public async Task<int> AddAsync({E} e) { await _ctx.{PE}.AddAsync(e); await _ctx.SaveChangesAsync(); return e.Id; } public async Task UpdateAsync({E} e) { _ctx.{PE}.Update(e); await _ctx.SaveChangesAsync(); } public async Task DeleteAsync(int id) { var entity = await _ctx.{PE}.FindAsync(id); if (entity != null) { entity.Delete(); await _ctx.SaveChangesAsync(); } } } '@ $e | % { $_.Replace("{PE}", $pE).Replace("{P}", $ProjectName).Replace("BTICK", "`"").Replace("{Cols}", $cols).Replace("{PagedSql}", $pagedSql) }) } } |