在中间件中注入实体框架上下文的存储库?

时间:2017-02-06 12:26:38

标签: c# asp.net-core-mvc entity-framework-core middleware

我正在创建一个内部微服务。我将标头中的域用户名传递给我的服务,我想确保无论使用什么用户名传递,无论哪个端点被调用,都存在相应的用户实体。 所以我添加了一个中间件,首先确保头部中存在用户名,并检查用户实体是否存在,如果不存在则创建它。

但是,当我调用多线程服务时,这会给我带来问题: 当我向服务发送多个请求时,服务会抛出一个带有&#34的InvalidOperation异常;附加信息:连接未关闭。连接的当前状态是开放的。"

这是异常转储:

  

{System.InvalidOperationException:连接未关闭。该   连接的当前状态正在连接。在   System.Data.ProviderBase.DbConnectionClosedConnecting.TryOpenConnection(的DbConnection   outerConnection,DbConnectionFactory connectionFactory,   TaskCompletionSource 1 retry, DbConnectionOptions userOptions) at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource 1   重试)在System.Data.SqlClient.SqlConnection.Open()处   Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open()
  在   Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable.Enumerator.BufferlessMoveNext(布尔   缓冲区)   Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerExecutionStrategy.Execute [TState,TResult](Func 2 operation, Func 2 verifySucceeded,TState state)at at   Microsoft.EntityFrameworkCore.Query.QueryMethodProvider&LT; _ShapedQuery&GT; d__3 1.MoveNext() at Microsoft.EntityFrameworkCore.Query.QueryMethodProvider.<_Include>d__30 1.MoveNext()   在   Microsoft.EntityFrameworkCore.Query.QueryMethodProvider&LT; _Include&GT; d__30 1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable 1   来自)lambda_method(Closure,QueryContext)at   Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler&LT;。&以及c

我的上下文和存储库注册:

        public void ConfigureServices(IServiceCollection services)
    {
        try
        {
            // Add framework services.
            services.AddApplicationInsightsTelemetry(Configuration);

            var connectionString = Startup.Configuration["connectionStrings:whiteApplicationsDbConnectionString"];
            services.AddDbContext<WhiteApplicationContext>(o => o.UseSqlServer(connectionString),ServiceLifetime.Scoped);

            services.AddMvc();

            services.AddScoped<IWhiteApplicationsRepository, WhiteApplicationsRepository>();
            services.AddScoped<IWhiteUserRepository, WhiteUserRepository>();
            services.AddScoped<IGroupRepository, GroupRepository>();
            services.AddScoped<IDiskUtils, DiskUtils>();
            ConfigureAutoMapper();





        }
        catch(Exception ex)
        {

            Console.WriteLine(ex.ToString());
            throw;
        }
    }

这是我注册中间件的方式:

app.UseMiddleware<ActiveDirectoryAuthenticationMiddleware>();

这是我的中间件实现:

public class ActiveDirectoryAuthenticationMiddleware
{
    private readonly IWhiteUserRepository _repository;
    private readonly RequestDelegate next;

    public ActiveDirectoryAuthenticationMiddleware(RequestDelegate next,IWhiteUserRepository _repository)
    {
        this.next = next;
        this._repository = _repository;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        if (!httpContext.Request.Headers.ContainsKey("Username"))
        {
            await ReturnBadRequest(httpContext, "Username");
        }

        if (!httpContext.Request.Headers.ContainsKey("Fullname"))
            await ReturnBadRequest(httpContext, "Fullname");


        if (!httpContext.Request.Headers.ContainsKey("MachineName"))
            await ReturnBadRequest(httpContext, "MachineName");


        var userName = httpContext.Request.Headers["Username"];
        var fullName = httpContext.Request.Headers["Fullname"];



        var user = _repository.GetUser(userName); //Exception is thrown here
        if (user == null)
            _repository.CreateUser(new DTOs.WhiteLogin { FullName = fullName, UserName = userName });






        await next.Invoke(httpContext);
    }

    private static async Task ReturnBadRequest(HttpContext httpContext, string missingValue)
    {
        httpContext.Response.StatusCode = 400;
        await httpContext.Response.WriteAsync($"{missingValue} missing");
        return;
    }



}

此行引发异常:

 var user = _repository.GetUser(userName);

这是我的用户存储库实现的一部分:

public class WhiteUserRepository : IWhiteUserRepository, IDisposable
{
    private WhiteApplicationContext ctx;

    public WhiteUserRepository(WhiteApplicationContext _ctx)
    {
        this.ctx = _ctx;
    }

    public void Dispose()
    {
        ctx.Dispose();
    }


    public WhiteUser GetUser(string username)
    {
        var user = ctx.WhiteUsers.Include(x => x.UserGroupWhiteUsers).Include(x => x.UserMachineConnections).FirstOrDefault(x => x.Username == username);




        return user;
    }

    public WhiteUser CreateUser(WhiteLogin whiteLogin)
    {
        var whiteUser = new WhiteUser { Username = whiteLogin.UserName, FullName = whiteLogin.FullName };

        ctx.WhiteUsers.Add(whiteUser);



        return whiteUser;
    }

如果我删除访问数据库的三行,那么一切正常。 我的用户存储库是作为作用域添加的,我在sql连接字符串上有多个活动结果集,但它仍然无法正常工作。 我还没有找到任何可以解释这种行为的东西..

有什么想法吗?

0 个答案:

没有答案