Reputation:
I have this project that is working fine:
service class:
public async Task<IAsyncEnumerable<ContratoDTO>> ContratoServiceGetAll()
{
List<ContratoDTO> listaDeContrato = new List<ContratoDTO>();
listaDeContrato = await ContratoRepository.GetAllAsync().Result.Select(u => new ContratoDTO(u)).ToList();
return listaDeContrato.ToAsyncEnumerable();
}
ViewComponent Class:
public async Task<IViewComponentResult> InvokeAsync()
{
ContratoViewModel listaContrato = new ContratoViewModel
{
Contratos = await ContratoSerivce.ContratoServiceGetAll()
};
return View(listaContrato);
}
and my component on the Shared View folder:
<tbody>
@if (Model.Contratos != null)
{
@foreach (var item in Model.Contratos.ToEnumerable())
{
<tr>
<th scope="row">@item.NuContrato</th>
<td>@item.VlContrato</td>
<td>36</td>
<td>@item.DtEmissao</td>
<td>@item.DtRetorno</td>
<td>Rio de Janeiro</td>
</tr>
}
}
</tbody>
It works but the Model.Contratos.ToEnumerable() is this the best approach ? If i take the ToEnumerable() method out it will throw an error:
'Error CS0202: foreach requires that the return type 'IAsyncEnumerator<ContratoDTO>' of 'IAsyncEnumerable<ContratoDTO>.GetEnumerator()' must have a suitable public MoveNext method and public'
ps: The ContratoViewModel has a property of IAsyncEnumerable generic type of T my DTO.
Upvotes: 0
Views: 1173
Reputation: 1
For all the years that I've been using Stack Overflow, this is my first time responding to anyone as I think it's time I should contribute to the community. I hope this is helpful.
IAsyncEnumerable<T>
can be awaited on similarly like Task<T>
. It doesn't need to be wrapped. A comment to your question shows that you may lose the benefit of IAsyncEnumerable<T>
if you use .Result.Select(u => new ContratoDTU(u)).ToList();
. I agree as .ToList()
is synchronous and will block until it's completed.
While using the variables in your service class, the following is a shorthanded revision:
public async IAsyncEnumerable<ContratoDTO> ContratoServiceGetAll()
{
foreach (var u in await ContratoRepository.GetAllAsync())
yield return new ContratoDTO(u);
}
Also, the .ToEnumerable()
statement in your component (assuming you meant .AsEnumerable()
from extension method Enumerable.AsEnumerable<TSource>(this IEnumerable<TSource> source)
) will cause the view to block at that moment to execute the Model.Contractos
query (again, assuming ContractoRepository.GetAllAsync()
is returning a IQueryable<T>
).
It's redundant to have .ToEnumerable()
as the the iteration will begin once @foreach (var item in Model.Contractos)
is evaluated.
Upvotes: 0