Refactor query behaviors to process action collections
Refactored BodyQueryBehavior and HeaderQueryBehavior to operate on collections of RecActionViewDto instead of single instances. Moved SQL execution and property assignment logic into private helper methods using ADO.NET commands. Improved null checks and logging, and updated type constraints to reflect the new usage. Behaviors now return the modified collection after processing.
This commit is contained in:
@@ -1,23 +1,41 @@
|
|||||||
using MediatR;
|
using MediatR;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using ReC.Application.Common.Dto;
|
using ReC.Application.Common.Dto;
|
||||||
using ReC.Application.Common.Interfaces;
|
using ReC.Application.Common.Interfaces;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace ReC.Application.Common.Behaviors.Action;
|
namespace ReC.Application.Common.Behaviors.Action;
|
||||||
|
|
||||||
public class BodyQueryBehavior<TRequest, TResponse>(IRecDbContext dbContext) : IPipelineBehavior<TRequest, TResponse>
|
public class BodyQueryBehavior<TRequest, TResponse>(IRecDbContext dbContext) : IPipelineBehavior<TRequest, TResponse>
|
||||||
where TRequest : RecActionViewDto
|
where TRequest : notnull
|
||||||
where TResponse : notnull
|
where TResponse : IEnumerable<RecActionViewDto>
|
||||||
{
|
{
|
||||||
public async Task<TResponse> Handle(TRequest action, RequestHandlerDelegate<TResponse> next, CancellationToken cancel)
|
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancel)
|
||||||
{
|
{
|
||||||
if (action.BodyQuery is null)
|
var actions = await next(cancel);
|
||||||
return await next(cancel);
|
|
||||||
|
|
||||||
var result = await dbContext.BodyQueryResults.FromSqlRaw(action.BodyQuery).SingleOrDefaultAsync(cancel);
|
foreach (var action in actions)
|
||||||
|
await SetBody(action, cancel);
|
||||||
|
|
||||||
action.Body = result?.RawBody;
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
return await next(cancel);
|
private async Task SetBody(RecActionViewDto action, CancellationToken cancel)
|
||||||
|
{
|
||||||
|
if (action.BodyQuery is not string bodyQuery)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await using var command = dbContext.Database.GetDbConnection().CreateCommand();
|
||||||
|
command.CommandText = bodyQuery;
|
||||||
|
|
||||||
|
await dbContext.Database.OpenConnectionAsync(cancel);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var scalar = await command.ExecuteScalarAsync(cancel);
|
||||||
|
action.Body = scalar as string;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
await dbContext.Database.CloseConnectionAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using MediatR;
|
using MediatR;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using ReC.Application.Common.Dto;
|
using ReC.Application.Common.Dto;
|
||||||
@@ -8,36 +8,53 @@ using System.Text.Json;
|
|||||||
namespace ReC.Application.Common.Behaviors.Action;
|
namespace ReC.Application.Common.Behaviors.Action;
|
||||||
|
|
||||||
public class HeaderQueryBehavior<TRequest, TResponse>(IRecDbContext dbContext, ILogger<HeaderQueryBehavior<TRequest, TResponse>>? logger = null) : IPipelineBehavior<TRequest, TResponse>
|
public class HeaderQueryBehavior<TRequest, TResponse>(IRecDbContext dbContext, ILogger<HeaderQueryBehavior<TRequest, TResponse>>? logger = null) : IPipelineBehavior<TRequest, TResponse>
|
||||||
where TRequest : RecActionViewDto
|
where TRequest : notnull
|
||||||
where TResponse : notnull
|
where TResponse : IEnumerable<RecActionViewDto>
|
||||||
{
|
{
|
||||||
public async Task<TResponse> Handle(TRequest action, RequestHandlerDelegate<TResponse> next, CancellationToken cancel)
|
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancel)
|
||||||
{
|
{
|
||||||
if (action.HeaderQuery is null)
|
var actions = await next(cancel);
|
||||||
return await next(cancel);
|
|
||||||
|
|
||||||
var result = await dbContext.HeaderQueryResults.FromSqlRaw(action.HeaderQuery).SingleOrDefaultAsync(cancel);
|
foreach (var action in actions)
|
||||||
|
await SetHeader(action, cancel);
|
||||||
|
|
||||||
if (result?.RawHeader is null)
|
return actions;
|
||||||
{
|
|
||||||
logger?.LogWarning("Header query did not return a result or returned a null REQUEST_HEADER. Profile ID: {ProfileId}, Action ID: {Id}", action.ProfileId, action.Id);
|
|
||||||
|
|
||||||
return await next(cancel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var headerDict = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(result.RawHeader);
|
private async Task SetHeader(RecActionViewDto action, CancellationToken cancel)
|
||||||
|
{
|
||||||
|
if (action.HeaderQuery is not string headerQuery)
|
||||||
|
return;
|
||||||
|
|
||||||
if(headerDict is null)
|
await using var command = dbContext.Database.GetDbConnection().CreateCommand();
|
||||||
|
command.CommandText = headerQuery;
|
||||||
|
|
||||||
|
await dbContext.Database.OpenConnectionAsync(cancel);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var scalar = await command.ExecuteScalarAsync(cancel);
|
||||||
|
|
||||||
|
if (scalar is not string rawHeader)
|
||||||
|
{
|
||||||
|
logger?.LogWarning("Header query did not return a result or returned a null value. Profile ID: {ProfileId}, Action ID: {Id}", action.ProfileId, action.Id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var headerDict = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(rawHeader);
|
||||||
|
|
||||||
|
if (headerDict is null)
|
||||||
{
|
{
|
||||||
logger?.LogWarning(
|
logger?.LogWarning(
|
||||||
"Header JSON deserialization returned null. RawHeader: {RawHeader}, ProfileId: {ProfileId}, Id: {Id}",
|
"Header JSON deserialization returned null. RawHeader: {RawHeader}, ProfileId: {ProfileId}, Id: {Id}",
|
||||||
result.RawHeader, action.ProfileId, action.Id);
|
rawHeader, action.ProfileId, action.Id);
|
||||||
|
return;
|
||||||
return await next(cancel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
action.Headers = headerDict.ToDictionary(header => header.Key, kvp => kvp.Value.ToString());
|
action.Headers = headerDict.ToDictionary(header => header.Key, kvp => kvp.Value.ToString());
|
||||||
|
}
|
||||||
return await next(cancel);
|
finally
|
||||||
|
{
|
||||||
|
await dbContext.Database.CloseConnectionAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user