在ASP.NET中,为什么DbSet.LastAsync()不存在?
我已经编写了一些代码来实现一些web API。 此API方法返回Foo表的最后一条记录在ASP.NET中,为什么DbSet.LastAsync()不存在?,asp.net,asp.net-web-api,async-await,entity-framework-6,Asp.net,Asp.net Web Api,Async Await,Entity Framework 6,我已经编写了一些代码来实现一些web API。 此API方法返回Foo表的最后一条记录 public class FooController : ApiController { private FooContext db = new FooContext(); // GET: api/Foo [ResponseType(typeof(Foo))] public async Task<IHttpActionResult> GetLastFoo()
public class FooController : ApiController
{
private FooContext db = new FooContext();
// GET: api/Foo
[ResponseType(typeof(Foo))]
public async Task<IHttpActionResult> GetLastFoo()
{
Foo foo = await db.Foo.Last();
if (foo == null)
{
return NotFound();
}
return Ok(foo);
}
}
公共类FooController:ApicController
{
private FooContext db=new FooContext();
//获取:api/Foo
[响应类型(类型(Foo))]
公共异步任务GetLastFoo()
{
Foo-Foo=wait db.Foo.Last();
if(foo==null)
{
返回NotFound();
}
返回Ok(foo);
}
}
我想使这个API异步,但没有LastAsync()方法。
为什么以及如何解决它?
提前谢谢。关于如何解决这个问题
你可以用
await Task.Run(()=>db.Foo.Last());
您不应在ASP.NET中使用Task.Run: ASP.NET上的Async和await都是关于I/O的。它们确实擅长于 读取和写入文件、数据库记录和RESTAPI。然而, 它们不适合CPU限制的任务。你可以开始一些背景知识 通过等待任务来工作。运行,但这样做没有意义。事实上 这实际上会通过干扰 ASP.NET线程池启发式。如果您有CPU绑定的工作要做 在ASP.NET中,最好是直接在请求上执行它 线一般来说,不要将工作排队到上的线程池 ASP.NET 从 但这并不意味着不能在ASP.NET中使用async和Wait进行I/O(这正是您想要的),只需使用真正的异步方法,而不是在同步方法上使用虚假的异步包装器(这只会将工作推送到其他线程池线程中,您会这样做)。
由于EF中没有LastAsync方法,我建议您使用OrderBy按需要对集合进行排序,并使用method(或支持lambda谓词的FirstAsync重载)而不是Last方法,FirstAsync是EF中支持的真正的异步I/O方法。
有关何时适合使用Task.Run的更多信息,可以在Stephen Cleary的博客文章中找到
你的问题是为什么没有LastAsync方法,应该直接问设计EF api的Microsoft团队,但我猜他们没有费心实现它,因为使用FirstAsync方法很容易实现我建议的相同功能。该代码的工作版本如下所示:
public class FooController : ApiController
{
private FooContext db = new FooContext();
// GET: api/Foo
[ResponseType(typeof(Foo))]
public async Task<IHttpActionResult> GetLastFoo()
{
Foo foo = await db.Foo.OrderByDesc(x=> x.Timestamp).FirstOrDefaultAsync();
if (foo == null)
{
return NotFound();
}
return Ok(foo);
}
}
公共类FooController:ApicController
{
private FooContext db=new FooContext();
//获取:api/Foo
[响应类型(类型(Foo))]
公共异步任务GetLastFoo()
{
Foo Foo=await db.Foo.OrderByDesc(x=>x.Timestamp).FirstOrDefaultAsync();
if(foo==null)
{
返回NotFound();
}
返回Ok(foo);
}
}
Last etc不适用于EF IQueryable,因为SQL没有等效的命令,但您不应该在ASP.NET中使用。它只会消耗资源,表现最差。你绝对不应该这样做。这会白白浪费资源。这没有好处。