0

我用Blazor server side和列出数据MudBlazor
我有一个用户列表:

用户列表.razor

public partial class UserList
{
    private async Task<TableData<User>> ServerReload(TableState state)
    {
        var admTableData = await _userService.GetUsersAsTableDataAsync(state.ToAdmTableState());
        return admTableData.ToTableData();
    }
}

用户列表的服务如下所示:

用户服务.cs

public class UserService
{
    public UserService(MyDbContext myDbContext)
    {
        _userRepository = new UserRepository(myDbContext);
    }

    public Task<AdmTableData<User>> GetUsersAsTableDataAsync(AdmTableState admTableState)
    {
        var queryable = _userRepository.GetUsersAsQueryable();

        if (!string.IsNullOrEmpty(admTableState.SearchString))
        {
            queryable = queryable.Where(u => u.Name.Contains(admTableState.SearchString, StringComparison.OrdinalIgnoreCase));
        }

        switch (admTableState.SortLabel)
        {
            case "Name":
                queryable = queryable.OrderByDirection(admTableState.SortDirection, o => o.Name);
                break;
        }

        return PaginationHelper.GetTableDataAsync(queryable, admTableState);
    }
}

pagination帮手:

分页助手.cs

public static async Task<AdmTableData<T>> GetTableDataAsync<T>(IQueryable<T> queryable, AdmTableState admTableState)
{
    var admTableData = new AdmTableData<T>();

    admTableData.TotalItems = await queryable.CountAsync();

    admTableData.Items = await queryable.Skip(admTableState.PageNumber * admTableState.PageSize)
        .Take(admTableState.PageSize).ToListAsync();

    return admTableData;
}

最后。我正在services通过以下方式注册:

程序.cs

builder.Services.AddDbContext<MyDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("myConnectionString")));

builder.Services.AddScoped<IUserService, UserService>();

如果我订购一列。我收到此错误:

Error: System.InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.

如果我进行搜索。它永远不会获取数据并继续加载:

永远加载截图

4

1 回答 1

1

如果您使用的是 Blazor 服务器端,则必须使用IDbContextFactory,因为您不能在多个线程中多次使用同一个 dbcontext 实例。

您的 dbcontext 服务是作用域的,这意味着它将在向服务器发出新请求时创建一个新实例,但 Blazor 服务器是一个单页应用程序,并且您有一个请求和单个 dbcontext 实例,如果您使用相同的 dbcontext一个普通的 asp.net 核心应用程序它会给你这个错误:

Error: System.InvalidOperationException: A second operation was started on this....

您必须手动创建 dbcontext 实例。像这样注册您的 dbcontext:

builder.Services.AddDbContextFactory<MyDbContext>(
     options => options.UseSqlServer(builder.Configuration.GetConnectionString("myConnectionString")));

并在您的代码中使用它,如下所示:

private readonly IDbContextFactory<MyDbContext> _contextFactory;

public MyController(IDbContextFactory<MyDbContext> contextFactory)
{
    _contextFactory = contextFactory;
}

public void DoSomething()
{
    using (var context = _contextFactory.CreateDbContext())
    {
        // ...
    }
}

您可以在DbContext Lifetime、Configuration 和 Initialization中阅读更多内容。

于 2022-01-18T20:31:50.397 回答