Async result for map using automapper

We are creating the Web.Api application of the angularjs application. Web.Api returns json result.

Step one received the data:

    public List<DataItem>> GetData()
    {
        return Mapper.Map<List<DataItem>>(dataRepository.GetData());
    }

It worked like a charm. Then we made async repo data, and we changed the code to work with it.

    public List<DataItem>> GetData()
    {
        return Mapper.Map<List<DataItem>>(dataRepository.GetDataAsync().Result);
    }

No problems. Now we wanted to make my Web.Api complete async awayt, so we changed it to:

    public async Task<List<DataItem>> GetData()
    {
        return await Mapper.Map<Task<List<DataItem>>>(dataRepository.GetDataAsync());
    }

At this point, Automapper gets confused. First, we had the following mapping rule: Mapper.CreateMap ();

This worked until the async web api method overflowed. An exception indicated that a card from

 Task<ICollection<Data>> to Task<ICollection<DataItem>>.

The converter has been changed to

Mapper.CreateMap<Task<List<Data>>, Task<List<DataItem>>>();

When checking the configuration, he complains that the result cannot be matched. How should we configure mappings?

+4
2

:

var data = await dataRepository.GetDataAsync();
return Mapper.Map<List<DataItem>>(data);

AutoMapper LINQ:

var data = await dbContext.Data.ProjectTo<DataItem>().ToListAsync();

, IQueryable ( ). .

+12

, :

    public static Task<TReturn> Convert<T, TReturn>(this Task<T> task)
    {
        if (task == null)
            throw new ArgumentNullException(nameof(task));

        var tcs = new TaskCompletionSource<TReturn>();

        task.ContinueWith(t => tcs.TrySetCanceled(), TaskContinuationOptions.OnlyOnCanceled);
        task.ContinueWith(t =>
        {
            tcs.TrySetResult(Mapper.Map<T, TReturn>(t.Result));
        }, TaskContinuationOptions.OnlyOnRanToCompletion);
        task.ContinueWith(t => tcs.TrySetException(t.Exception), TaskContinuationOptions.OnlyOnFaulted);

        return tcs.Task;
    }


    public static Task<List<TReturn>> ConvertEach<T, TReturn>(this Task<List<T>> task)
    {
        if (task == null)
            throw new ArgumentNullException(nameof(task));

        var tcs = new TaskCompletionSource<List<TReturn>>();

        task.ContinueWith(t => tcs.TrySetCanceled(), TaskContinuationOptions.OnlyOnCanceled);
        task.ContinueWith(t =>
        {
            tcs.TrySetResult(t.Result.Select(Mapper.Map<T, TReturn>).ToList());
        }, TaskContinuationOptions.OnlyOnRanToCompletion);
        task.ContinueWith(t => tcs.TrySetException(t.Exception), TaskContinuationOptions.OnlyOnFaulted);

        return tcs.Task;
    }
0

Source: https://habr.com/ru/post/1607650/


All Articles