使用异步编程键入转换错误

时间:2014-01-06 13:20:17

标签: c# entity-framework asynchronous

有谁能告诉我为什么这不起作用?

我有一个看起来像这样的方法:

public virtual async Task<IList<User>> GetAll()
{
    return this.db.Users.Where(model => model.CompanyId.Equals(this.companyId, StringComparison.OrdinalIgnoreCase)).ToListAsync();
}

当我尝试编译我的代码时,我得到一个错误说明:

  

错误10无法隐式转换类型'System.Threading.Tasks.Task&gt;'到'System.Collections.Generic.IList'。存在显式转换(您是否缺少演员?)C:\ Users \ Jaymie \ Documents \ GitHub \ Skipstone \ Skipstone.Web \ Repositories \ UserRepository.cs 70 20 Skipstone.Web

然而直接在其下我有这个方法:

public Task<User> FindByIdAsync(string userId)
{
    return this.db.Users.Where(model => model.Id.Equals(userId, StringComparison.OrdinalIgnoreCase)).SingleOrDefaultAsync();
}

工作正常。

我想我看不到树木的树木,所以需要别人的眼睛来帮助我:)

2 个答案:

答案 0 :(得分:12)

ToListAsync方法会返回一个Task<List<T>>对象,该对象会转换为您案例中的Task<List<User>>对象,但您的方法的返回类型为Task<IList<User>>

此处的问题是T中的Task<T>不支持协方差。

因此,要么将方法的返回类型更改为Task<List<User>>,要么编写代码以自行进行转换:

return this.db.Users
    .Where(model => model.Id.Equals(userId, StringComparison.OrdinalIgnoreCase))
    .ToListAsync()
    .ContinueWith<IList<User>>(t => t.Result, TaskContinuationOptions.ExecuteSynchronously);

答案 1 :(得分:3)

如果您使用的是async关键字,则需要使用await关键字返回原始类型。

public virtual async Task<IList<User>> GetAll()
{
    return await this.db.Users.Where(model =>
         model.CompanyId.Equals(this.companyId, 
              StringComparison.OrdinalIgnoreCase)).ToListAsync().ConfigureAwait(false);;
}

或者没有异步,您需要像在第二个正在运行的示例中那样指定类型Task。