Compare commits
7 Commits
1e54b775a2
...
a757749767
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a757749767 | ||
|
|
5166f41941 | ||
|
|
928f2a7780 | ||
|
|
d46aa6e2b8 | ||
|
|
7cffc3f7bc | ||
|
|
841da3c261 | ||
|
|
adbfd69418 |
@@ -1,12 +1,12 @@
|
||||
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
|
||||
/// <summary>
|
||||
/// Provides methods for executing common Entity Framework queries on a given entity type.
|
||||
/// This interface abstracts away the direct usage of Entity Framework methods for querying data
|
||||
/// Provides methods for executing common queries on a given entity type.
|
||||
/// This interface abstracts away the direct usage of ORM libraries (such as Entity Framework) for querying data
|
||||
/// and provides asynchronous and synchronous operations for querying a collection or single entity.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The type of the entity being queried.</typeparam>
|
||||
public interface IQueryExecutor<TEntity>
|
||||
public interface IQuery<TEntity>
|
||||
{
|
||||
/// <summary>
|
||||
/// Asynchronously retrieves the first entity or a default value if no entity is found.
|
||||
@@ -5,23 +5,23 @@
|
||||
/// Provides abstraction for raw SQL execution as well as mapping the results to <typeparamref name="TEntity"/> objects.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The entity type to which the SQL query results will be mapped.</typeparam>
|
||||
public interface ISQLExecutor<TEntity>
|
||||
public interface ISQLExecutor<TEntity>: ISQLExecutor
|
||||
{
|
||||
/// <summary>
|
||||
/// Executes a raw SQL query and returns an <see cref="IQueryExecutor{TEntity}"/> for further querying operations on the result.
|
||||
/// Executes a raw SQL query and returns an <see cref="IQuery{TEntity}"/> for further querying operations on the result.
|
||||
/// </summary>
|
||||
/// <param name="sql">The raw SQL query to execute.</param>
|
||||
/// <param name="cancellation">Optional cancellation token for the operation.</param>
|
||||
/// <param name="parameters">Optional parameters for the SQL query.</param>
|
||||
/// <returns>An <see cref="IQueryExecutor{TEntity}"/> instance for further query operations on the result.</returns>
|
||||
IQueryExecutor<TEntity> Execute(string sql, CancellationToken cancellation = default, params object[] parameters);
|
||||
/// <returns>An <see cref="IQuery{TEntity}"/> instance for further query operations on the result.</returns>
|
||||
IQuery<TEntity> Execute(string sql, CancellationToken cancellation = default, params object[] parameters);
|
||||
|
||||
/// <summary>
|
||||
/// Executes a custom SQL query defined by a class that implements <see cref="ISQL{TEntity}"/> and returns an <see cref="IQueryExecutor{TEntity}"/> for further querying operations on the result.
|
||||
/// Executes a custom SQL query defined by a class that implements <see cref="ISQL{TEntity}"/> and returns an <see cref="IQuery{TEntity}"/> for further querying operations on the result.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSQL">The type of the custom SQL query class implementing <see cref="ISQL{TEntity}"/>.</typeparam>
|
||||
/// <param name="cancellation">Optional cancellation token for the operation.</param>
|
||||
/// <param name="parameters">Optional parameters for the SQL query.</param>
|
||||
/// <returns>An <see cref="IQueryExecutor{TEntity}"/> instance for further query operations on the result.</returns>
|
||||
IQueryExecutor<TEntity> Execute<TSQL>(CancellationToken cancellation = default, params object[] parameters) where TSQL : ISQL<TEntity>;
|
||||
/// <returns>An <see cref="IQuery{TEntity}"/> instance for further query operations on the result.</returns>
|
||||
IQuery<TEntity> Execute<TSQL>(CancellationToken cancellation = default, params object[] parameters) where TSQL : ISQL<TEntity>;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using Dapper;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface ISQLExecutor
|
||||
{
|
||||
/// <summary>
|
||||
/// Executes a raw SQL query and returns an <see cref="IQuery{TEntity}"/> for further querying operations on the result.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The entity type to which the SQL query results will be mapped.</typeparam>
|
||||
/// <param name="sql">The raw SQL query to execute.</param>
|
||||
/// <param name="parameters">Parameters for the SQL query.</param>
|
||||
/// <param name="cancellation">Optional cancellation token for the operation.</param>
|
||||
/// <returns>An <see cref="IQuery{TEntity}"/> instance for further query operations on the result.</returns>
|
||||
Task<IEnumerable<TEntity>> Execute<TEntity>(string sql, DynamicParameters parameters, CancellationToken cancellation = default);
|
||||
|
||||
/// <summary>
|
||||
/// Executes a custom SQL query defined by a class that implements <see cref="ISQL{TEntity}"/> and returns an <see cref="IQuery{TEntity}"/> for further querying operations on the result.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The entity type to which the SQL query results will be mapped.</typeparam>
|
||||
/// <typeparam name="TSQL">The type of the custom SQL query class implementing <see cref="ISQL{TEntity}"/>.</typeparam>
|
||||
/// <param name="parameters">Parameters for the SQL query.</param>
|
||||
/// <param name="cancellation">Optional cancellation token for the operation.</param>
|
||||
/// <returns>An <see cref="IQuery{TEntity}"/> instance for further query operations on the result.</returns>
|
||||
Task<IEnumerable<TEntity>> Execute<TEntity, TSQL>(DynamicParameters parameters, CancellationToken cancellation = default) where TSQL : ISQL;
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Dapper" Version="2.1.66" />
|
||||
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.6.0" />
|
||||
<PackageReference Include="DigitalData.Core.Application" Version="3.2.1" />
|
||||
<PackageReference Include="DigitalData.Core.Client" Version="2.0.3" />
|
||||
@@ -20,6 +21,7 @@
|
||||
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.0.0" />
|
||||
<PackageReference Include="MediatR" Version="12.5.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.18" />
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.4" />
|
||||
<PackageReference Include="Otp.NET" Version="1.4.0" />
|
||||
<PackageReference Include="QRCoder" Version="1.6.0" />
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using MediatR;
|
||||
using EnvelopeGenerator.Application.Envelopes.Commands;
|
||||
using MediatR;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace EnvelopeGenerator.Application.EnvelopeReceivers.Commands.Create;
|
||||
@@ -17,7 +18,7 @@ public record CreateEnvelopeReceiverCommand(
|
||||
[Required] DocumentCreateCommand Document,
|
||||
[Required] IEnumerable<ReceiverGetOrCreateCommand> Receivers,
|
||||
bool TFAEnabled = false
|
||||
) : IRequest;
|
||||
) : CreateEnvelopeCommand(Title, Message, TFAEnabled), IRequest;
|
||||
|
||||
#region DTOs
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Envelopes.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// Befehl zur Erstellung eines Umschlags.
|
||||
/// </summary>
|
||||
/// <param name="Title">Der Titel des Umschlags. Dies ist ein Pflichtfeld.</param>
|
||||
/// <param name="Message">Die Nachricht, die im Umschlag enthalten sein soll. Dies ist ein Pflichtfeld.</param>
|
||||
/// <param name="TFAEnabled">Gibt an, ob die Zwei-Faktor-Authentifizierung für den Umschlag aktiviert ist. Standardmäßig false.</param>
|
||||
public record CreateEnvelopeCommand(
|
||||
[Required] string Title,
|
||||
[Required] string Message,
|
||||
bool TFAEnabled = false
|
||||
) : IRequest<CreateEnvelopeResponse?>
|
||||
{
|
||||
/// <summary>
|
||||
/// Id of receiver
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
[BindNever]
|
||||
public int? UserId { get; set; }
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
using AutoMapper;
|
||||
using Dapper;
|
||||
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using MediatR;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Envelopes.Commands;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CreateEnvelopeCommandHandler : IRequestHandler<CreateEnvelopeCommand, CreateEnvelopeResponse?>
|
||||
{
|
||||
private readonly ISQLExecutor<Envelope> _sqlExecutor;
|
||||
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sqlExecutor"></param>
|
||||
/// <param name="mapper"></param>
|
||||
public CreateEnvelopeCommandHandler(ISQLExecutor<Envelope> sqlExecutor, IMapper mapper)
|
||||
{
|
||||
_sqlExecutor = sqlExecutor;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<CreateEnvelopeResponse?> Handle(CreateEnvelopeCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var parameters = new DynamicParameters();
|
||||
parameters.Add("@UserId", request.UserId);
|
||||
parameters.Add("@Title", request.Title);
|
||||
parameters.Add("@TfaEnabled", request.TFAEnabled ? 1 : 0);
|
||||
parameters.Add("@Message", request.Message);
|
||||
|
||||
var envelopes = await _sqlExecutor.Execute<Envelope, CreateEnvelopeSQL>(parameters, cancellationToken);
|
||||
|
||||
return _mapper.Map<CreateEnvelopeResponse>(envelopes.FirstOrDefault());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using AutoMapper;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Envelopes.Commands;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CreateEnvelopeMappingProfile : Profile
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public CreateEnvelopeMappingProfile()
|
||||
{
|
||||
CreateMap<Envelope, CreateEnvelopeResponse>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Envelopes.Commands;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="Id"><inheritdoc/></param>
|
||||
/// <param name="UserId"><inheritdoc/></param>
|
||||
/// <param name="Status"><inheritdoc/></param>
|
||||
/// <param name="Uuid"><inheritdoc/></param>
|
||||
/// <param name="Message"><inheritdoc/></param>
|
||||
/// <param name="AddedWhen"><inheritdoc/></param>
|
||||
/// <param name="ChangedWhen"><inheritdoc/></param>
|
||||
/// <param name="Title"><inheritdoc/></param>
|
||||
/// <param name="Language"><inheritdoc/></param>
|
||||
/// <param name="TFAEnabled"><inheritdoc/></param>
|
||||
/// <param name="User"><inheritdoc/></param>
|
||||
public record CreateEnvelopeResponse(int Id, int UserId, int Status, string Uuid, string? Message, DateTime AddedWhen, DateTime? ChangedWhen, string? Title, string Language, bool TFAEnabled, DigitalData.UserManager.Domain.Entities.User User)
|
||||
: ReadEnvelopeResponse(Id, UserId, Status, Uuid, Message, AddedWhen, ChangedWhen, Title, Language, TFAEnabled, User);
|
||||
@@ -0,0 +1,29 @@
|
||||
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
namespace EnvelopeGenerator.Application.Envelopes.Commands;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CreateEnvelopeSQL : ISQL<Envelope>
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Raw => @"
|
||||
USE [DD_ECM];
|
||||
DECLARE @OUT_UID varchar(36);
|
||||
|
||||
EXEC [dbo].[PRSIG_API_CREATE_ENVELOPE]
|
||||
@USER_ID = @UserId,
|
||||
@TITLE = @Title,
|
||||
@TFAEnabled = @TfaEnabled,
|
||||
@MESSAGE = @Message,
|
||||
@OUT_UID = @OUT_UID OUTPUT;
|
||||
|
||||
SELECT TOP(1) *
|
||||
FROM [dbo].[TBSIG_ENVELOPE]
|
||||
WHERE [ENVELOPE_UUID] = @OUT_UID;
|
||||
";
|
||||
}
|
||||
@@ -5,10 +5,14 @@ namespace EnvelopeGenerator.GeneratorAPI.Controllers
|
||||
{
|
||||
public static class ControllerExtensions
|
||||
{
|
||||
public static int? GetId(this ClaimsPrincipal user)
|
||||
=> int.TryParse(user.FindFirst(ClaimTypes.NameIdentifier)?.Value, out int result)
|
||||
public static int? GetIdOrDefault(this ClaimsPrincipal user)
|
||||
=> int.TryParse(user.FindFirstValue(ClaimTypes.NameIdentifier) ?? user.FindFirstValue("sub"), out int result)
|
||||
? result : null;
|
||||
|
||||
|
||||
public static int GetId(this ClaimsPrincipal user)
|
||||
=> user.GetIdOrDefault()
|
||||
?? throw new InvalidOperationException("User ID claim is missing or invalid. This may indicate a misconfigured or forged JWT token.");
|
||||
|
||||
public static string? GetUsername(this ClaimsPrincipal user)
|
||||
=> user.FindFirst(ClaimTypes.Name)?.Value;
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
using DigitalData.Core.DTO;
|
||||
using EnvelopeGenerator.Application.Contracts.Services;
|
||||
using EnvelopeGenerator.Application.Envelopes.Commands;
|
||||
using EnvelopeGenerator.Application.Envelopes.Queries.Read;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||
|
||||
@@ -27,16 +30,19 @@ public class EnvelopeController : ControllerBase
|
||||
{
|
||||
private readonly ILogger<EnvelopeController> _logger;
|
||||
private readonly IEnvelopeService _envelopeService;
|
||||
private readonly IMediator _mediator;
|
||||
|
||||
/// <summary>
|
||||
/// Erstellt eine neue Instanz des EnvelopeControllers.
|
||||
/// </summary>
|
||||
/// <param name="logger">Der Logger, der für das Protokollieren von Informationen verwendet wird.</param>
|
||||
/// <param name="envelopeService">Der Dienst, der für die Verarbeitung von Umschlägen zuständig ist.</param>
|
||||
public EnvelopeController(ILogger<EnvelopeController> logger, IEnvelopeService envelopeService)
|
||||
/// <param name="mediator"></param>
|
||||
public EnvelopeController(ILogger<EnvelopeController> logger, IEnvelopeService envelopeService, IMediator mediator)
|
||||
{
|
||||
_logger = logger;
|
||||
_envelopeService = envelopeService;
|
||||
_mediator = mediator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -75,4 +81,33 @@ public class EnvelopeController : ControllerBase
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="envelope"></param>
|
||||
/// <returns></returns>
|
||||
[Authorize]
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> CreateAsync([FromQuery] CreateEnvelopeCommand envelope)
|
||||
{
|
||||
try
|
||||
{
|
||||
envelope.UserId = User.GetId();
|
||||
var res = await _mediator.Send(envelope);
|
||||
|
||||
if (res is null)
|
||||
{
|
||||
_logger.LogError("Failed to create envelope. Envelope details: {EnvelopeDetails}", JsonConvert.SerializeObject(envelope));
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
else
|
||||
return Ok(res);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "{Message}", ex.Message);
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using DigitalData.Core.Infrastructure;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using DigitalData.Core.Infrastructure.AutoMapper;
|
||||
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
|
||||
namespace EnvelopeGenerator.Infrastructure;
|
||||
|
||||
@@ -59,6 +60,42 @@ public static class DIExtensions
|
||||
services.AddDbRepository<EGDbContext, UserReceiver>(context => context.UserReceivers).UseAutoMapper();
|
||||
services.AddDbRepository<EGDbContext, EnvelopeReceiverReadOnly>(context => context.EnvelopeReceiverReadOnlys).UseAutoMapper();
|
||||
|
||||
services.AddSQLExecutor<Envelope>();
|
||||
services.AddSQLExecutor<Receiver>();
|
||||
services.AddSQLExecutor<EnvelopeDocument>();
|
||||
services.AddSQLExecutor<DocumentReceiverElement>();
|
||||
services.AddSQLExecutor<DocumentStatus>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddSQLExecutor<T>(this IServiceCollection services) where T : class
|
||||
{
|
||||
services.AddScoped<ISQLExecutor<T>, SQLExecutor<T>>();
|
||||
|
||||
var interfaceType = typeof(ISQL<>);
|
||||
var targetGenericType = interfaceType.MakeGenericType(typeof(T));
|
||||
|
||||
var implementations = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.SelectMany(a =>
|
||||
{
|
||||
try { return a.GetTypes(); }
|
||||
catch { return Array.Empty<Type>(); }
|
||||
})
|
||||
.Where(t =>
|
||||
t is { IsClass: true, IsAbstract: false } &&
|
||||
t.GetInterfaces().Any(i =>
|
||||
i.IsGenericType &&
|
||||
i.GetGenericTypeDefinition() == interfaceType &&
|
||||
i.GenericTypeArguments[0] == typeof(T)
|
||||
)
|
||||
);
|
||||
|
||||
foreach (var impl in implementations)
|
||||
{
|
||||
services.AddSingleton(impl);
|
||||
}
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Dapper" Version="2.1.66" />
|
||||
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.6.0" />
|
||||
<PackageReference Include="DigitalData.Core.Infrastructure" Version="2.0.4" />
|
||||
<PackageReference Include="DigitalData.Core.Infrastructure.AutoMapper" Version="1.0.2" />
|
||||
|
||||
@@ -4,11 +4,11 @@ using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace EnvelopeGenerator.Infrastructure;
|
||||
|
||||
public sealed record QueryExecutor<TEntity> : IQueryExecutor<TEntity>
|
||||
public sealed record Query<TEntity> : IQuery<TEntity>
|
||||
{
|
||||
private readonly IQueryable<TEntity> _query;
|
||||
|
||||
internal QueryExecutor(IQueryable<TEntity> queryable)
|
||||
internal Query(IQueryable<TEntity> queryable)
|
||||
{
|
||||
_query = queryable;
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace EnvelopeGenerator.Infrastructure;
|
||||
|
||||
public static class QueryExecutorExtension
|
||||
{
|
||||
public static QueryExecutor<TEntity> ToExecutor<TEntity>(this IQueryable<TEntity> queryable) where TEntity : class
|
||||
{
|
||||
return new QueryExecutor<TEntity>(queryable);
|
||||
}
|
||||
}
|
||||
9
EnvelopeGenerator.Infrastructure/QueryExtension.cs
Normal file
9
EnvelopeGenerator.Infrastructure/QueryExtension.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace EnvelopeGenerator.Infrastructure;
|
||||
|
||||
public static class QueryExtension
|
||||
{
|
||||
public static Query<TEntity> ToQuery<TEntity>(this IQueryable<TEntity> queryable) where TEntity : class
|
||||
{
|
||||
return new Query<TEntity>(queryable);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,31 @@
|
||||
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Dapper;
|
||||
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace EnvelopeGenerator.Infrastructure;
|
||||
|
||||
public sealed class SQLExecutor<T> : ISQLExecutor<T> where T : class
|
||||
public class SQLExecutor : ISQLExecutor
|
||||
{
|
||||
private readonly EGDbContext _context;
|
||||
private readonly string _cnnStr = "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=dd;Encrypt=false;TrustServerCertificate=True;";
|
||||
|
||||
private readonly IServiceProvider _provider;
|
||||
|
||||
public SQLExecutor(EGDbContext context, IServiceProvider provider)
|
||||
public SQLExecutor(IServiceProvider provider)
|
||||
{
|
||||
_context = context;
|
||||
_provider = provider;
|
||||
}
|
||||
|
||||
public IQueryExecutor<T> Execute(string sql, CancellationToken cancellation = default, params object[] parameters)
|
||||
=> _context
|
||||
.Set<T>()
|
||||
.FromSqlRaw(sql, parameters)
|
||||
.ToExecutor();
|
||||
public async Task<IEnumerable<TEntity>> Execute<TEntity>(string sql, DynamicParameters parameters, CancellationToken cancellation = default)
|
||||
{
|
||||
using var connection = new SqlConnection(_cnnStr);
|
||||
await connection.OpenAsync(cancellation);
|
||||
return await connection.QueryAsync<TEntity>(sql, parameters);
|
||||
}
|
||||
|
||||
public IQueryExecutor<T> Execute<TSQL>(CancellationToken cancellation = default, params object[] parameters) where TSQL : ISQL<T>
|
||||
public Task<IEnumerable<TEntity>> Execute<TEntity, TSQL>(DynamicParameters parameters, CancellationToken cancellation = default) where TSQL : ISQL
|
||||
{
|
||||
var sql = _provider.GetRequiredService<TSQL>();
|
||||
return Execute(sql.Raw);
|
||||
return Execute<TEntity>(sql.Raw, parameters, cancellation);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
EnvelopeGenerator.Infrastructure/SQLExecutorBaseEntity.cs
Normal file
30
EnvelopeGenerator.Infrastructure/SQLExecutorBaseEntity.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using EnvelopeGenerator.Application.Contracts.SQLExecutor;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace EnvelopeGenerator.Infrastructure;
|
||||
|
||||
public sealed class SQLExecutor<T> : SQLExecutor, ISQLExecutor<T> where T : class
|
||||
{
|
||||
private readonly EGDbContext _context;
|
||||
|
||||
private readonly IServiceProvider _provider;
|
||||
|
||||
public SQLExecutor(EGDbContext context, IServiceProvider provider) : base(provider)
|
||||
{
|
||||
_context = context;
|
||||
_provider = provider;
|
||||
}
|
||||
|
||||
public IQuery<T> Execute(string sql, CancellationToken cancellation = default, params object[] parameters)
|
||||
=> _context
|
||||
.Set<T>()
|
||||
.FromSqlRaw(sql, parameters)
|
||||
.ToQuery();
|
||||
|
||||
public IQuery<T> Execute<TSQL>(CancellationToken cancellation = default, params object[] parameters) where TSQL : ISQL<T>
|
||||
{
|
||||
var sql = _provider.GetRequiredService<TSQL>();
|
||||
return Execute(sql.Raw);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user