我有一个运行良好的项目:
服务类别:
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类:
public async Task<IViewComponentResult> InvokeAsync()
{
ContratoViewModel listaContrato = new ContratoViewModel
{
Contratos = await ContratoSerivce.ContratoServiceGetAll()
};
return View(listaContrato);
}
和我的共享视图文件夹上的组件:
<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>
它可以工作,但是Model.Contratos.ToEnumerable()是最好的方法吗?如果我取出ToEnumerable()方法,它将抛出错误:
'Error CS0202: foreach requires that the return type 'IAsyncEnumerator<ContratoDTO>' of 'IAsyncEnumerable<ContratoDTO>.GetEnumerator()' must have a suitable public MoveNext method and public'
ps:ContratoViewModel具有T my DTO的IAsyncEnumerable通用类型的属性。
答案 0 :(得分:1)
多年来,我一直在使用Stack Overflow,这是我第一次回应任何人,因为我认为这是我应该为社区做出贡献的时候。我希望这会有所帮助。
IAsyncEnumerable<T>
可以像Task<T>
一样等待。它不需要被包装。对问题的评论表明,如果您使用IAsyncEnumerable<T>
,则可能会失去.Result.Select(u => new ContratoDTU(u)).ToList();
的好处。我同意.ToList()
是同步的,并且会阻塞直到完成。
使用服务类中的变量时,以下内容是简写形式:
public async IAsyncEnumerable<ContratoDTO> ContratoServiceGetAll()
{
foreach (var u in await ContratoRepository.GetAllAsync())
yield return new ContratoDTO(u);
}
此外,组件中的.ToEnumerable()
语句(假设您是指扩展方法.AsEnumerable()
中的Enumerable.AsEnumerable<TSource>(this IEnumerable<TSource> source)
)将导致视图在此时阻塞以执行Model.Contractos
查询(同样,假设ContractoRepository.GetAllAsync()
返回IQueryable<T>
)。
使用.ToEnumerable()
是多余的,因为一旦评估了@foreach (var item in Model.Contractos)
,迭代就会开始。