在尝试从我的数据库中获取行时,我遇到了使用FirstOrDefaultAsync
抛出InvalidCastException
的问题。如果我在没有异步的情况下切换到FirstOrDefault
,那么它会正确加载数据。
作品
public async Task<Application> GetApplication(int id)
{
return _context.Applications.FirstOrDefault(a => a.Id == id);
}
不起作用
public async Task<Application> GetApplication(int id)
{
return await _context.Applications.FirstOrDefaultAsync(a => a.Id == id);
}
application
表的架构如下所示:
CREATE TABLE `application` (
`id` INTEGER NOT NULL,
`name` TEXT NOT NULL UNIQUE,
`application_id` TEXT NOT NULL UNIQUE,
`secret_key` TEXT NOT NULL UNIQUE,
PRIMARY KEY(id)
);
数据库中的数据是:
+----+---------+----------------+------------+
| id | name | application_id | secret_key |
+----+---------+----------------+------------+
| 1 | TestApp | app123 | secret123 |
+----+---------+----------------+------------+
堆栈跟踪的前几行如下:
at System.Data.Common.DbDataReader.GetFieldValue[T](Int32 ordinal)
at System.Data.Common.DbDataReader.GetFieldValueAsync[T](Int32 ordinal, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
由于id
是表格中唯一的Int32字段,我猜测EF正在努力使用此属性,但我无法解决使用FirstOrDefault
时其工作原理的问题。有什么想法吗?
我正在使用.NET 4.5.1的实体框架6。
提前致谢!
答案 0 :(得分:1)
你能否更新你的问题,正如你所说的那样,真的不应该 - FirstOrDefault()不会返回Task,所以你会得到一个强制转换异常。
您需要的是
public async Task<Application> GetApplicationAsync(int id)
{
return await _context.Applications.FirstOrDefaultAsync(a => a.Id == id);
}
答案 1 :(得分:1)
由于您使用的是异步方法,因此需要使用
public async Task<Application> GetApplication(int id)
{
return await _context.Applications.FirstOrDefaultAsync(a => a.Id == id);
}
但实际上您的Id列是主键,因此您可以使用其他linq扩展方法来完成您的任务,例如
public async Task<Application> GetApplication(int id)
{
return await _context.Applications.FindAsync(id);
}
FindAsync(id)
基本上是为基于primary key
的选择而设计的。所以建议使用FindAsync()
。添加
命名空间:System.ServiceModel.Discovery 程序集:System.ServiceModel.Discovery(在System.ServiceModel.Discovery.dll中)
实际上你正在使用,我认为Sqlite不是线程安全的,所以你甚至不希望它处理异步请求。有一个库可以使Sqlite异步,但我不知道它是否运行良好。但请尝试github.com/oysteinkrog/SQLite.Net-PCL