QUERY : Build and Fetch Pattern

BasicCRUD Insert Query with Bridge

Now, let us understand the build and fetch pattern using which we execute all our queries.

The query gets executed in the process or end point where pre-bus runs.

So before that, let us have a look at our controller action GetCustomerById.

public partial class CustomerController : FlexControllerBridge
{
[HttpGet()]
[Route("GetCustomerById/{id}")]
public GetCustomerByIdOutputAPIModel GetCustomerById(string id)
{
GetCustomerByIdParams parameters = new GetCustomerByIdParams();
FlexHostContextInfoBridge hostContextInfo = new FlexHostContextInfoBridge();
hostContextInfo.Populate<IFlexHostHttpContextAccesorBridge>(_appHttpContextAccessor);
parameters.SetHostContextInfo(hostContextInfo);
parameters.Id = id;
return ProcessCustomerService.GetCustomerById(parameters);
}
}

If you notice here, we have the GetCustomerById and passing the Id in an instance of GetCustomerbyIdParams. Let's see what is the definition of this?

So it is located in our Query projects.

public class GetCustomerByIdParams : FlexiQueryParameterBridge
{
public string Id { get; set; }
}

It is HostContext is being accessed here and we are passing the parameter here. So even if you need the tenant information or user information in the queries you have easily accessible there. Now let us understand the query.

public class GetCustomerById : FlexiQueryBridge<Customer, GetCustomerByIdOutputAPIModel>
{
private string _Id;
private IFlexQueryRepositoryBridge _repoFlex;
readonly ILogger<GetCustomerById> _logger;
private GetCustomerByIdParams _params;
IMapper _mapper;
IReadDbConnectionProviderBridge _connectionProvider;
/// <summary>
///
/// </summary>
/// <param name="repoFlex"></param>
/// <param name="logger"></param>
public GetCustomerById(IFlexQueryRepositoryBridge repoFlex, ILogger<GetCustomerById> logger, IMapper mapper, IReadDbConnectionProviderBridge connectionProvider)
{
_repoFlex = repoFlex;
_logger = logger;
_mapper = mapper;
_connectionProvider = connectionProvider;
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public GetCustomerById AssignParameters(GetCustomerByIdParams @params)
{
_params = @params;
return this;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public override GetCustomerByIdOutputAPIModel Fetch()
{
var stopwatch = Stopwatch.StartNew();
var result = Build<Customer>().ProjectTo<GetCustomerByIdOutputAPIModel>(_mapper.ConfigurationProvider).FirstOrDefault();
Trace.WriteLine($"Query GetCustomerById execution time: {stopwatch.ElapsedMilliseconds} ms");
return result;
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
protected override IQueryable<T> Build<T>()
{
_connectionProvider.ConfigureDbConnectionString(_params.GetHostContextInfo());
_repoFlex.InitializeConnection(_connectionProvider);
IQueryable<T> query = _repoFlex.FindAll<T>().Where(t => t.Id == _params.Id);
return query;
}
}
public class GetCustomerByIdParams : FlexiQueryParameterBridge
{
public string Id { get; set; }
}

We will use the IFlexQueryRepositoryBridge and the IReadDbConnectionProviderBridge instead of the IWriteDbConnectionProviderBridge. We are using a ProjectTo is a very handy auto-mapper method that maps the data and queries only those fields mentioned in the output model, which is a happy scenario for the DBA. So, whatever you define in the output API model, it will fetch only those fields from the database. And a lot of time saved in writing long select statements even in LINQ.

So let us see that in action in the next section.