Asp.net 在上一个操作之前,在此上下文上启动了第二个操作

Asp.net 在上一个操作之前,在此上下文上启动了第二个操作,asp.net,entity-framework,graphql,dbcontext,Asp.net,Entity Framework,Graphql,Dbcontext,我在使用EntityFramework时有一个常见错误,但我无法找出原因。错误是 “在上一个操作之前,在此上下文上启动了第二个操作 操作已完成。这通常是由使用 DbContext的相同实例。有关如何避免 DbContext的线程问题,请参阅 " 我正在使用GraphQL中间件来处理请求 堆栈跟踪: at Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection() at Microsoft

我在使用EntityFramework时有一个常见错误,但我无法找出原因。错误是

“在上一个操作之前,在此上下文上启动了第二个操作 操作已完成。这通常是由使用 DbContext的相同实例。有关如何避免 DbContext的线程问题,请参阅 "

我正在使用GraphQL中间件来处理请求

堆栈跟踪:

at Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
   at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
   at Test.DataAccess.Intranet.Repository.Admin.UserModule.Query.GetUserDataQuery.Execute(String username) in C:\Projects\GIT Projects\SWDi\Intranet\Test.Backend\Test.DataAccess.Intranet\Repository\Modules\Admin\UserManagement\Query\Implementation\GetUserDataQuery.cs:line 34
   at Test.Web.Base.Services.UserService.GetUserContext(HttpContext context) in C:\Projects\GIT Projects\Test\Intranet\Test.Backend\Test.Web.Base\Services\UserService.cs:line 55
   at Test.API.Middleware.GraphQLMiddleware.InvokeAsync(HttpContext httpContext) in C:\Projects\GIT Projects\Test\Intranet\Test.Backend\Test.Web.API\Middleware\GraphQLMiddleware.cs:line 71
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Test.Web.API.Middleware.NtlmAndAnonymousSetupMiddleware.Invoke(HttpContext context) in C:\Projects\GIT Projects\Test\Intranet\SWDi.Backend\Test.Web.API\Middleware\NtlmAndAnonymousSetupMiddleware.cs:line 39
   at Test.API.Middleware.ExceptionMiddleware.Invoke(HttpContext context) in C:\Projects\GIT Projects\Test\Intranet\Test.Backend\Test.Web.API\Middleware\ExceptionMiddleware.cs:line 40"
在这里,我在graphqlmidware.cs中处理POST请求:

public async Task InvokeAsync(HttpContext httpContext)
        {
            if (
                (httpContext.Request.Path.StartsWithSegments(CATCHURLPATH) || httpContext.Request.PathBase.StartsWithSegments(CATCHURLPATH))
                && string.Equals(httpContext.Request.Method, CATCHURLMETHOD, StringComparison.OrdinalIgnoreCase))
            {
                string body;

                var userContext = await this.userService.GetUserContext(httpContext);
                using (var streamReader = new StreamReader(httpContext.Request.Body))
                {
                    body = await streamReader.ReadToEndAsync();
                    var request = JsonConvert.DeserializeObject<GraphQLQueryBase>(body);
                    var result = await this.executor.ExecuteAsync(doc =>
                    {
                        doc.ThrowOnUnhandledException = true;
                        doc.Schema = this.schema;
                        doc.Query = request.Query;
                        doc.Inputs = request.Variables.ToInputs();
                        doc.ExposeExceptions = true;
                        doc.UserContext = new Dictionary<string, object>()
                        {
                            { "UserId", userContext.UserId },
                            { "Username", userContext.Username },
                        };
                    }).ConfigureAwait(false);

#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                    Task.Factory.StartNew(() => this.queryLogMutation.Execute(userContext.UserId, request.Query));
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed

                    httpContext.Response.ContentType = "application/json";
                    await this.writer.WriteAsync(httpContext.Response.Body, result);
                }
            }
            else
            {
                await this.next(httpContext);
            }
        }
最后是
getUserByUsername
查询:

public class GetUserDataQuery : IGetUserDataQuery
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="GetUserDataQuery"/> class.
        /// </summary>
        /// <param name="context">Intranet Context by DI.</param>
        public GetUserDataQuery(IntranetContext context)
        {
            this.Context = context;
        }

        private IntranetContext Context { get; }

        /// <summary>
        /// Get the Intranet user context using the users (AD) username.
        /// </summary>
        /// <param name="username">The username.</param>
        /// <returns>The DB user context.</returns>
        public async Task<MainUserModel> Execute(string username)
        {
            var userInformation = await this.Context.VUser.Where(x => x.Username == username).SingleOrDefaultAsync();
            var userRights = await this.Context.UserModule.Where(x => x.UserId == userInformation.UserId).Include(x => x.RefModule).ToListAsync();
            var userFunctions = await this.Context.UserModuleFunction.Where(x => x.UserId == userInformation.UserId).Include(x => x.RefModuleFunction).ToListAsync();
            var memberList = await this.Context.UserGroupMember.Where(x => x.UserId == userInformation.UserId).Include(x => x.UserGroup).ToListAsync();
            var isCashier = await this.Context.UserCashbox.Where(x => x.UserId == userInformation.UserId).AnyAsync();
            return new MainUserModel(userInformation, userFunctions, userRights, memberList, isCashier);
        }
    }
公共类GetUserDataQuery:IGetUserDataQuery { /// ///初始化类的新实例。 /// ///由DI提供的Intranet上下文。 公共GetUserDataQuery(IntranetContext上下文) { this.Context=Context; } 私有IntranetContext上下文{get;} /// ///使用用户(AD)用户名获取Intranet用户上下文。 /// ///用户名。 ///数据库用户上下文。 公共异步任务执行(字符串用户名) { var userInformation=wait this.Context.VUser.Where(x=>x.Username==Username.SingleOrDefaultAsync(); var userRights=wait this.Context.UserModule.Where(x=>x.UserId==userInformation.UserId); var userFunctions=wait this.Context.UserModuleFunction.Where(x=>x.UserId==userInformation.UserId).Include(x=>x.RefModuleFunction.toListSync(); var memberList=wait this.Context.UserGroupMember.Where(x=>x.UserId==userInformation.UserId).Include(x=>x.UserGroup.toListSync(); var isCashier=wait this.Context.UserCashbox.Where(x=>x.UserId==userInformation.UserId).AnyAsync(); 返回新的MainUserModel(用户信息、用户函数、用户权限、成员列表、iCashier); } } 即使我将我的
dbContext
设置为瞬态,检查是否有忘记的async/await关键字,甚至是嵌套的async,错误仍然会发生。
如果您需要进一步的信息或有任何想法,请让我知道。

在线`var dbuser=等待此消息。GetUserByUserName查询…`
getUserByUsernameQuery
是如何构造和分配的?@DavidBrowne-Microsoft我添加了剩余的userService代码。
userService
从哪里获取其
IGetUserDataQuery
构造函数参数?@DavidBrowne-Microsoft我不太确定您需要看到什么。我对.NET相当缺乏经验。你能详细说明一下吗?对于初学者来说,这是一个相当复杂的设计。该错误告诉您,您的
IntranetContext
被两个不同的操作同时使用。您将
IntranetContext
嵌入到多个级别的服务中,因此您必须跟踪如何实例化这些服务并管理它们的生命周期。如果其中一个是单例,或者如果您显式地并行使用它们,则可能会导致此错误。
public class GetUserDataQuery : IGetUserDataQuery
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="GetUserDataQuery"/> class.
        /// </summary>
        /// <param name="context">Intranet Context by DI.</param>
        public GetUserDataQuery(IntranetContext context)
        {
            this.Context = context;
        }

        private IntranetContext Context { get; }

        /// <summary>
        /// Get the Intranet user context using the users (AD) username.
        /// </summary>
        /// <param name="username">The username.</param>
        /// <returns>The DB user context.</returns>
        public async Task<MainUserModel> Execute(string username)
        {
            var userInformation = await this.Context.VUser.Where(x => x.Username == username).SingleOrDefaultAsync();
            var userRights = await this.Context.UserModule.Where(x => x.UserId == userInformation.UserId).Include(x => x.RefModule).ToListAsync();
            var userFunctions = await this.Context.UserModuleFunction.Where(x => x.UserId == userInformation.UserId).Include(x => x.RefModuleFunction).ToListAsync();
            var memberList = await this.Context.UserGroupMember.Where(x => x.UserId == userInformation.UserId).Include(x => x.UserGroup).ToListAsync();
            var isCashier = await this.Context.UserCashbox.Where(x => x.UserId == userInformation.UserId).AnyAsync();
            return new MainUserModel(userInformation, userFunctions, userRights, memberList, isCashier);
        }
    }