在 C# 中根据每个请求切换多个数据库

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

我需要用 C# .net core 编写一个控制台应用程序。此控制台应用程序应订阅事件中心。它侦听事件中心,当它通过事件中心接收到消息时,它会读取消息并进行处理。该消息包含客户 ID 和处理数据所需的一些其他信息。

在数据库中,我们为每个客户创建了数据库。数据库名称等于客户 ID。现在 C# 服务需要根据消息中收到的客户 ID 动态连接到数据库。

我正在使用实体框架来编写代码。

我在 startup.cs 中使用 DBConext 在 Web API 中做了类似的工作,如下所示:

 services.AddDbContext<CustomerContext>(options =>
            {
                var serviceProvider = services.BuildServiceProvider();
                var httpRouteData = serviceProvider.GetService<IHttpContextAccessor>()?.HttpContext?.GetRouteData();
                var db = httpRouteData?.Values["customerId"]?.ToString();
                db = db?.Replace('-', '_');
                options.UseNpgsql(
                        new NpgsqlConnectionStringBuilder
                        {
                            Host = "Hostname",
                            Port = "port",
                            SslMode = SslMode.Require,
                            Username = "username",
                            Database = db,
                            Password = "password",
                            Timeout = 1024,
                            CommandTimeout = 60000
                        }.ConnectionString
                    );
            }); 
        

所以每个请求,基于 httpcontext 路由数据中的 customerId,我们能够动态地形成连接字符串。并通过依赖注入使用这个 DBContext。如何在控制台应用程序中实现此功能?

c# entity-framework console-application
1个回答
0
投票

您可以创建一个方法来为客户每次获取 dbcontext connectionstring。

  public class CustomerContextFactory : IDisposable
{
    private readonly Dictionary<string, CustomerContext> _dbContexts = new Dictionary<string, CustomerContext>();

    public CustomerContext GetContext(string customerId)
    {
        if (!_dbContexts.TryGetValue(customerId, out var context))
        {
            var connectionString = new NpgsqlConnectionStringBuilder
            {
                Host = "Hostname",
                Port = "port",
                SslMode = SslMode.Require,
                Username = "username",
                Database = customerId.Replace('-', '_'),
                Password = "password",
                Timeout = 1024,
                CommandTimeout = 60000
            }.ConnectionString;

            var optionsBuilder = new DbContextOptionsBuilder<CustomerContext>()
                .UseNpgsql(connectionString);

            context = new CustomerContext(optionsBuilder.Options);
            _dbContexts.Add(customerId, context);
        }

        return context;
    }

    public void Dispose()
    {
        foreach (var context in _dbContexts.Values)
        {
            context.Dispose();
        }
    }
}

使用它获取消息中客户 ID 的 DbContext 实例:

void HandleEvent(EventData eventData)
{
    var customerId = eventData.Properties["CustomerId"].ToString();
    using (var contextFactory = new CustomerContextFactory())
    using (var context = contextFactory.GetContext(customerId))
    {
        // Use the context to process the message
        // ...
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.