Blazor 服务器端的 FromResult 或 IServiceScopeFactory

FromResult or IServiceScopeFactory in Blazor server-side

所以我一直在将 IServiceScopeFactory 注入我的页面,以便在通过 EF Core 获取数据时使用它的范围。 但是昨天我偶然发现有人在调用数据库时使用 Task.FromResult 。 一个比另一个更受欢迎吗?如果是,为什么?

提前致谢!

例如Task.FromResult

//In code behind
[Inject]
IMyService myService { get; set; }

protected void GetSomeData()
{
   var someData = await myServie.GetSomeData(); 
}

//From serviceClass
public async Task<List<SomeData>> GetSomeData(int id)
{
   return await Task.FromResult(db.SomeTable.Where(x => x.Id == qualifierVersionId).AsEnumerable());
}

例如

//In code behind
[Inject]
IServiceScopeFactory ScopeFactory { get; set; }
protected void GetSomeData()
{
   using (var serviceScope = ScopeFactory.CreateScope())
   {
       var myService = serviceScope.ServiceProvider.GetService<IMyService>();

       var someData = await myServie.GetSomeData(); 
   }
}

//From serviceClass
public async Task<List<SomeData>> GetSomeData(int id)
{
   return await db.SomeTable.Where(x => x.Id == id).ToListAsync();
}

编辑(因为为什么我想知道走哪条路的问题)

我需要使用一个或另一个,因为在使用服务器端 Blazor 时,生命周期会使 Scoop 表现得像一个 Singleton。因此,如果我调用 return await db.SomeTable.Where(x => x.Id == id).ToListAsync();没有 IServiceScopeFactory 它将一直存在,直到您关闭网站。所以这会产生一个错误:'A second operation started on this context before a previous operation completed.'.

您不能将两者进行比较,因为它们没有任何共同点。

Task.FromResult 只是创建一个成功完成并具有指定结果的任务。我相信使用 Task.FromResult 的主要用例之一是当您实现异步接口但您的实现是同步的时,如上例所示。这对数据库调用来说并不是一个好主意,因为它们可能需要很长时间。

我不确定您为什么要使用上面的 IServiceScopeFactory。如果这样的话,您所请求的服务的范围就是您所请求的组件的生命周期,那么还有更好的方法。

public class MyComponent : OwningComponentBase<IMyService>
{
    protected void GetSomeData(int id)
    {
        var someData = await Service.GetSomeData(id);
    }
}

public class MyService : IMyService
{
    public async Task<List<SomeData>> GetSomeData(int id)
    {
        return await db.SomeTable.Where(x => x.Id == id).ToListAsync();
    }
}

通过使用 OwningComponentBase,在后台为您创建了一个服务范围,并且该服务由基本组件通过 Service 属性 公开。如果你想了解更多,我已经 written a blog post 了。