Вот мой рабочий код:
Код: Выделить всё
var allUsers = _userManager.Users.OrderBy(x => x.FirstName);
var usersViewModel = new List();
foreach (var user in allUsers)
{
var tempVm = new UsersViewModel()
{
Id = user.Id,
UserName = user.UserName,
FirstName = user.FirstName,
LastName = user.LastName,
DisplayName = user.DisplayName,
Email = user.Email,
Enabled = user.Enabled,
Roles = String.Join(", ", await _userManager.GetRolesAsync(user))
};
usersViewModel.Add(tempVm);
}
< /code>
В попытке упростить код я подумал, что могу сделать что -то подобное
(сломанный код) < /strong>: < /p>
var usersViewModel = allUsers.Select(user => new UsersViewModel
{
Id = user.Id,
UserName = user.UserName,
FirstName = user.FirstName,
LastName = user.LastName,
DisplayName = user.DisplayName,
Email = user.Email,
Enabled = user.Enabled,
Roles = string.Join(", ", await _userManager.GetRolesAsync(user))
}).ToList();
Я предполагаю, что метод getRolesAsync () возвращает задачу и назначает ее ролям вместо фактических результатов этой задачи. Что я не могу понять для меня жизни, так это то, как заставить ее работать. Вот несколько, на которые я посмотрел:
Можно ли назвать ожидаемый метод в методе без асинхронности?
https: // blogs .msdn.microsoft.com/pfxteam/2012/04/12/asyncawait-faq/
Вызовный метод Async in ienumerable.select
Ожидайте список задач, асинхронно с использованием linq?
Как использовать асинхро Коллекция < /p>
Признательно, я не до конца понимаю, как асинхронно /ожидаю работы, так что это, вероятно, является частью проблемы. Мой код Foreach работает, но я бы хотел понять, как заставить его работать так, как я пытаюсь. Поскольку я уже потратил на это так много времени, я подумал, что это был бы хороший первый вопрос. < /P>
Спасибо! /strong> < /p>
Я думаю, мне нужно объяснить, что я делал в каждом случае статей, которые я исследовал, чтобы это не было помечено как дублированный вопрос - и я действительно старался изо всех сил Избегайте этого:-/. Хотя вопрос звучит одинаково, результаты не являются. В случае статьи, которая была отмечена как ответ, я попробовал следующий код: < /p>
public async Task Users()
{
var allUsers = _userManager.Users.OrderBy(x => x.FirstName);
var tasks = allUsers.Select(GetUserViewModelAsync).ToList();
return View(await Task.WhenAll(tasks));
}
public async Task GetUserViewModelAsync(ApplicationUser user)
{
return new UsersViewModel
{
Id = user.Id,
UserName = user.UserName,
FirstName = user.FirstName,
LastName = user.LastName,
DisplayName = user.DisplayName,
Email = user.Email,
Enabled = user.Enabled,
Roles = String.Join(", ", await _userManager.GetRolesAsync(user))
};
}
< /code>
Я также пытался использовать Asenumerable, как SO: < /p>
var usersViewModel = allUsers.AsEnumerable().Select(async user => new UsersViewModel
{
Id = user.Id,
UserName = user.UserName,
FirstName = user.FirstName,
LastName = user.LastName,
DisplayName = user.DisplayName,
Email = user.Email,
Enabled = user.Enabled,
Roles = string.Join(", ", await _userManager.GetRolesAsync(user))
}).ToList();
< /code>
Оба из них создают сообщение об ошибке: »InvalidoperationException: Вторая операция началась в этом контексте до выполнения предыдущей операции. Любые участники экземпляра не гарантируют, что они будут безопасными».
На данный момент кажется, что моя оригинальная предварительная фанати Сделайте это, используя асинхронные методы. < /p>
edit 2 - с ответом < /strong>
благодаря комментариям Ценга (и некоторым другим исследованиям) я смог сделать вещи Работайте, используя следующий код: < /p>
var userViewModels = allUsers.Result.Select(async user => new UsersViewModel
{
Id = user.Id,
UserName = user.UserName,
FirstName = user.FirstName,
LastName = user.LastName,
DisplayName = user.DisplayName,
Email = user.Email,
Enabled = user.Enabled,
Roles = string.Join(", ", await _userManager.GetRolesAsync(user))
});
var vms = await Task.WhenAll(userViewModels);
return View(vms.ToList());
< /code>
Хотя теперь, когда я принял во внимание комментарии всех, я начал смотреть ближе к SQL Profiler, просто чтобы увидеть, сколько попадает БД на самом деле - как упоминал Мэтт Джонсон, это много (N+1). < /P>
Так что, хотя это отвечает на мой вопрос, я теперь пересматриваю, как запустить запрос и может просто отбросить роли в основном представлении и только потянуть их как каждый, как каждый, как каждый Пользователь выбран. Я определенно многому научился через этот вопрос (и узнал больше о том, чего я не знаю), так что спасибо всем.
Подробнее здесь: https://stackoverflow.com/questions/395 ... ect-lambda
Мобильная версия