在 Blazor 服务器中使用实体框架获取联接数据时出现 InvalidOperationException

问题描述 投票:0回答:1

我正在开发一个 Blazor 服务器端项目,我需要在

OnInitializedAsync
方法中使用 Entity Framework Core 从多个表中获取和联接数据。但是,我遇到以下错误:

InvalidOperationException:在上一个操作完成之前,在此上下文实例上启动了第二个操作。这通常是由不同线程同时使用同一个 DbContext 实例引起的。

下面是我的代码:

protected override async Task OnInitializedAsync()
{

    PeopleTypes = await DbContext.PeopleTypes.Select(pts => new PeopleType
        {
            Id = pts.Id,
            TypeName = pts.TypeName
        }).ToListAsync() ?? new List<PeopleType>();

    Peoples = await DbContext.People.Select(pl => new People
        {
            Id = pl.Id,
            Name = pl.Name,
            CompanyId = pl.CompanyId,
            TypeId = pl.TypeId
        }).ToListAsync() ?? new List<People>();

    CompanyLists = await DbContext.CompanyList.Select(cl => new CompanyList
        {
            Id = cl.Id,
            CompanyName = cl.CompanyName
        }).ToListAsync() ?? new List<CompanyList>();

    ClassDetails = await DbContext.ClassSessionsDetails
    .Where(csd => csd.CsID == CSId)
    .Where(csd => csd.CompanyId == selectedCompany)
    .Select(csd => new ClassSessionDetails
        {
            Id = csd.Id,
            CsID = csd.CsID
        }).ToListAsync();

    classMembersData = await DbContext.ClassSessionsDetails
        .Join(DbContext.ClassSessionsMembers,
            csd => csd.Id,
            csm => csm.CSD_Id,
            (csd, csm) => new { csd, csm })
        .Join(DbContext.People,
            combined => combined.csm.PeopleId,
            people => people.Id,
            (combined, people) => new { combined.csd, combined.csm, people })
        .GroupJoin(DbContext.CompanyList,
            combined => combined.people.CompanyId,
            company => company.Id,
            (combined, companies) => new { combined.csd, combined.csm, combined.people, company = companies.FirstOrDefault() })
        .GroupJoin(DbContext.PeopleTypes,
            combined => combined.people.TypeId,
            peopleType => peopleType.Id,
            (combined, peopleTypes) => new { combined.csd, combined.csm, combined.people, combined.company, peopleType = peopleTypes.FirstOrDefault() })
        .Select(result => new ClassMembers
            {
                PeopleId = result.people.Id,
                Name = result.people.Name,
                CompanyId = result.company.Id,
                CompanyName = result.company.CompanyName,
                PeopleTypeId = result.peopleType.Id,
                PeopleTypeName = result.peopleType.TypeName
            }).ToListAsync();

    await base.OnInitializedAsync();
}

有人对如何解决此问题有建议,或者如何改进查询以避免并发操作冲突?谢谢你。

c# asynchronous blazor blazor-server-side
1个回答
0
投票

将多个查询合并为一个查询,以避免对 DbContext 进行多次异步调用。这样可以避免并发操作,提高性能。

这是样本

protected override async Task OnInitializedAsync()
{
    var result = await (
        from csd in DbContext.ClassSessionsDetails
        join csm in DbContext.ClassSessionsMembers on csd.Id equals csm.CSD_Id
        join p in DbContext.People on csm.PeopleId equals p.Id
        join cl in DbContext.CompanyList on p.CompanyId equals cl.Id into companyGroup
        from company in companyGroup.DefaultIfEmpty()
        join pt in DbContext.PeopleTypes on p.TypeId equals pt.Id into peopleTypeGroup
        from peopleType in peopleTypeGroup.DefaultIfEmpty()
        where csd.CsID == CSId && csd.CompanyId == selectedCompany
        select new ClassMembers
        {
            PeopleId = p.Id,
            Name = p.Name,
            CompanyId = company != null ? company.Id : (int?)null,
            CompanyName = company != null ? company.CompanyName : null,
            PeopleTypeId = peopleType != null ? peopleType.Id : (int?)null,
            PeopleTypeName = peopleType != null ? peopleType.TypeName : null
        }
    ).ToListAsync();

    classMembersData = result;

    await base.OnInitializedAsync();
}
© www.soinside.com 2019 - 2024. All rights reserved.