簡體   English   中英

EF Core 根據 API 中的參數調用數據庫

[英]EF Core to call database based on parameter in API

我有一個 API 在 .NET Core 和 EF Core 中開發。 我必須為多個客戶提供不同的數據(但相同的模式)。 這是一個學校申請,由於競爭等原因,每所學校都希望單獨保存他們的數據。所以我們為每所學校都有一個數據庫。 現在我的挑戰是,基於一些參數,我想更改我的dbContext object 的連接字符串。

例如,如果我調用 api/students/1 它應該得到所有來自學校 1 的學生,依此類推。 我不確定在配置服務本身中是否有更好的方法來做到這一點。 但我應該能夠從我的客戶端應用程序中傳遞SchoolId

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<SchoolDataContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("APIConnectionString")));
    services.AddScoped<IUnitOfWorkLearn, UnitOfWorkLearn>();
}

2021 年 5 月 11 日


namespace LearnNew
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //Comenting to implement Mr Brownes Solution
            //services.AddDbContext<SchoolDataContext>(options =>
            //   options.UseSqlServer(
            //       Configuration.GetConnectionString("APIConnectionString")));



            services.AddScoped<IUnitOfWorkLearn, UnitOfWorkLearn>();


            services.AddControllers();


            services.AddHttpContextAccessor();

            services.AddDbContext<SchoolDataContext>((sp, options) =>
            {
                var requestContext = sp.GetRequiredService<HttpContext>();
                var constr = GetConnectionStringFromRequestContext(requestContext);
                options.UseSqlServer(constr, o => o.UseRelationalNulls());

            });

            ConfigureSharedKernelServices(services);

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "LearnNew", Version = "v1" });
            });
        }

        private string GetConnectionStringFromRequestContext(HttpContext requestContext)
        {
            //Trying to implement Mr Brownes Solution
            var host = requestContext.Request.Host;
            // Since I don't know how to get the connection string, I want to  
            //debug the host variable and see the possible way to get details of 
            //the host. Below line is temporary until the right method is identified
            return Configuration.GetConnectionString("APIConnectionString");
        }

        private void ConfigureSharedKernelServices(IServiceCollection services)
        {
            ServiceProvider serviceProvider = services.BuildServiceProvider();
            SchoolDataContext appDbContext = serviceProvider.GetService<SchoolDataContext>();

            services.RegisterSharedKernel(appDbContext);
        }

            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "LearnNew v1"));
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }



    }
}

您可以在配置 DbContext 時訪問 HttpContext,如下所示:

        services.AddControllers();

        services.AddHttpContextAccessor();

        services.AddDbContext<SchoolDataContext>((sp, options) =>
        {
            var requestContext = sp.GetRequiredService<IHttpContextAccessor>().HttpContext;
            var constr = GetConnectionStringFromRequestContext(requestContext);
            options.UseSqlServer(constr, o => o.UseRelationalNulls());

        });

這段代碼:

            var requestContext = sp.GetRequiredService<IHttpContextAccessor>().HttpContext;                var constr = GetConnectionStringFromRequestContext(requestContext);
            options.UseSqlServer(constr, o => o.UseRelationalNulls());

將為每個請求運行,根據來自 HttpRequestContext 的詳細信息配置連接字符串。

如果您需要在啟動時使用您的 DbContext,請不要通過 DI 解決它。 只需像這樣配置一個連接:

        var ob  = new DbContextOptionsBuilder<SchoolDataContext>();
        var constr = "...";
        ob.UseSqlServer(constr);
        using (var db = new Db(ob.Options))
        {
            db.Database.EnsureCreated();
        }

但在生產中,您通常會提前創建所有租戶數據庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM