Search code examples
c#automapperdtocqrsmediatr

C# MediatR: Return nested/compound DTO


I want to return a compound/nested DTO SearchDto which includes Status(timeMs, resultsFound) and List<SearchResult>.

Example JSON DTO

{
status: {
        timeMs: 0.038583,
        found: 728,
    },
    results: [
        {
            id: "c00f9c89-0683-4818-9043-0df10704f7dc",
            score: "32.03388",
            fields: {
                id: "f42d2a0d-3a30-4cb6-940f-fb474b82588b",
                type: "client",
                title: "Business Pty Ltd",
                description: "Client from Australia",
                status: "Active",
                url: "#client/f42d2a0d-3a30-4cb6-940f-fb474b82588b"
            }
        }
]}

SearchDto.cs

    // The Search Result Data Transfer Object
    public record SearchDto(SearchStatusDto status, IEnumerable<SearchResultDto> results);

    // Status contains metadata about the search
    public record SearchStatusDto(double timeMs, int found);

    // Each Search Result has a unique ID and relevancy score; then contains the payload containing the result
    public record SearchResultDto(Guid id, double score, SearchResultFieldsDto fields);

    // Actual search data that gets displayed
    public record SearchResultFieldsDto(Guid id, string type, string title, string description, string status, string url);

GetSearchResultsQueryHandler.cs

public async Task<SearchDto> Handle(GetSearchResultsQuery request, CancellationToken cancellationToken)
        {
            // Getsome data from the Search Results Entity.
            var items = await context.SearchResult.AsNoTracking().ToListAsync();
            // Map it to the Search Result Dto.
            var results = mapper.Map<IEnumerable<SearchResultDto>>(items);
            // Create the status object with example data.
            var SearchStatusDto status = new SearchStatusDto(0.00383, 500);
            // Amalgamate the status and List<Result> and return. (not implemented)
            return results;
        }

Problem

The problem that I am running into is:

The name 'status' does not exist in the current context [OrganisationName.Services.Api]csharp(CS0103)

I'm pretty new to C#, .Net, and MediatR, so I"m not sure if I'm even approaching the problem correctly. Is it even possible/advisable to use MediatR like this?


Solution

  • The solution is to construct the SearchDto before returning it.

    public async Task<SearchDto> Handle(GetSearchResultsQuery request, CancellationToken cancellationToken)
    {
        var items = await context.People.AsNoTracking().ToListAsync();
        var results = mapper.Map<IEnumerable<SearchResultDto>>(items);
        return new SearchDto(
            new SearchStatusDto(0.03838, 300),
            results
        );
    }