RND*_*hts 1 c# lambda async-await
我正在尝试使用实体框架从表中执行Lambda Select到新模型,但我需要能够调用异步方法来填充返回集中每个实例上的属性:
await Task.WhenAll(_context.UserContacts.Where(uc => uc.UserId == user.Id).Select(async uc => new MailContact
{
Email = uc.Contact.Email,
UserId = uc.Contact.UserId,
ContactId = uc.Contact.Id,
Name = uc.Contact.UserId != null ? await _graphService.GetUserByIdAsync(uc.Contact.UserId) : null;
}
Run Code Online (Sandbox Code Playgroud)
我知道Linq对await/async的支持有限,我在StackOverflow上看了几个其他的例子,其中异步部分被移动到一个单独的循环中,例如:
T[] data = await Task.WhenAll(contacts.Select(c => LoadDataAsync(c)));
Run Code Online (Sandbox Code Playgroud)
但是,这种方法不会让我更新被称为"c"的对象,除非我通过引用传递异步方法不允许的引用.
有人可以解释正确填充名称属性的最有效方法吗?
您只需要在LINQ-to-Objects中进行辅助查找,而不是LINQ-to-Entities:
// LINQ-to-Entities
var users = await _context.UserContacts
.Where(uc => uc.UserId == user.Id)
.Select(uc => new
{
uc.Contact.Email,
uc.Contact.UserId,
ContactId = uc.Contact.Id,
})
.ToListAsync();
// LINQ-to-Objects
var lookupTasks = users.Select(async u => new
{
u.Email,
u.UserId,
u.ContactId,
Name = u.UserId != null ? await _graphService.GetUserByIdAsync(u.UserId) : null;
});
return await Task.WhenAll(lookupTasks);
Run Code Online (Sandbox Code Playgroud)
我们的想法是将尽可能多的逻辑推入最初的LINQ-to-Entities查询,包括过滤和投影.然后你执行它(ToListAsync).
然后,您获取数据库结果并执行辅助查找.
| 归档时间: |
|
| 查看次数: |
2206 次 |
| 最近记录: |