asp.net核心中的IAsyncEnumerable视图组件返回

时间:2018-10-11 04:53:19

标签: c# asynchronous asp.net-core-viewcomponent

我有一个运行良好的项目:

服务类别:

 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通用类型的属性。

1 个答案:

答案 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),迭代就会开始。