Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如何用2个不同的连接注册相同的DB上下文?_.net_Asp.net Core_.net Core - Fatal编程技术网

.net 如何用2个不同的连接注册相同的DB上下文?

.net 如何用2个不同的连接注册相同的DB上下文?,.net,asp.net-core,.net-core,.net,Asp.net Core,.net Core,是否可以在.Net Core中用两个不同的连接字符串注册相同的DB上下文? 并且,根据头中传递的内容使用这两个上下文中的任意一个 谢谢 您将需要两个DBContext public class MyContext : DbContext { public DbSet<Car> Cars {get; set; } public DbSet<Motorcycle> Motorcycles { get; set; } } public class MyFirs

是否可以在.Net Core中用两个不同的连接字符串注册相同的DB上下文? 并且,根据头中传递的内容使用这两个上下文中的任意一个


谢谢

您将需要两个DBContext

public class MyContext : DbContext
{
    public DbSet<Car> Cars {get; set; }
    public DbSet<Motorcycle> Motorcycles { get; set; }
}

public class MyFirstContext : MyContext
{

}

public class MySecondContext : MyContext
{

}
公共类MyContext:DbContext
{
公共数据库集车辆{get;set;}
公共DbSet摩托车{get;set;}
}
公共类MyFirstContext:MyContext
{
}
公共类MySecondContext:MyContext
{
}
然后你可以这样注册它们:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<MyFirstContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("FirstConnection")));

    services.AddDbContext<MySecondContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("SecondConnection")));
}
public void配置服务(IServiceCollection服务)
{
services.AddDbContext(选项=>
options.UseSqlServer(Configuration.GetConnectionString(“FirstConnection”));
services.AddDbContext(选项=>
options.UseSqlServer(Configuration.GetConnectionString(“SecondConnection”));
}

祝你好运。

我很快就把这段代码拼凑起来了。未经测试,可能需要一些修改才能工作。主要的一点是不要使用标准的DI注册,而是使用您自己的工厂来创建上下文

public class DbContextFactory
{
    public DbContext Create(string contextTarget)
    {
        var optionsBuilder = new DbContextOptionsBuilder();
        // use contextTarget to create/read the correct connection string here
        optionsBuilder.UseSqlServer(@"Server=.\SQLEXPRESS;Database=Blogging;integrated security=True;");
        var context = new BloggingContext(optionsBuilder.Options);
    }
}
然后在配置中注册它:

services.AddScoped<DbContextFactory>();

问题并不是很清楚,所以让我们假设实际的问题是访问多租户数据库。Gunnar Peipman撰写了一篇关于如何在ASP.NET核心中实现多租户的演示文稿,其中一篇专门针对和

解决方案实际上非常简单-让上下文通过注入服务请求正确的连接:

public class PlaylistContext : DbContext
{
    private readonly Tenant _tenant;

    public DbSet<Playlist> Playlists { get; set; }
    public DbSet<Song> Songs { get; set; }

    public PlaylistContext(DbContextOptions<PlaylistContext> options,
                            ITenantProvider tenantProvider)
        : base(options)
    {
        _tenant = tenantProvider.GetTenant();
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(_tenant.DatabaseConnectionString);

        base.OnConfiguring(optionsBuilder);
    }
...
}
剩下的就是注册所有上下文和依赖项。再说一次,没什么特别的:

services.AddDbContext<TenantsContext>(options => options.UseSqlServer(connection));
services.AddScoped<ITenantProvider, WebTenantProvider>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddDbContext(options=>options.UseSqlServer(connection));
services.addScope();
services.AddSingleton();

如果决定使用哪个连接字符串所需的所有信息都在标题中,这是最简单的解决方案:

// needed below
services.AddHttpContextAccessor();

// register DbContext with options that change depending on request's header
services.AddDbContext<DatabaseContext>((provider, builder) =>
{
    // get current HttpContext
    HttpContext context = provider.GetRequiredService<IHttpContextAccessor>().HttpContext;

    // get relevant header
    var headerValue = context.Request.Headers["user-agent"].Single();

    // create relevant connection string based on header value and configure context to run against SQL Server
    var connectionString = CreateConnectionString(headerValue);
    builder.UseSqlServer(connectionString);
});
//下面需要
AddHttpContextAccessor();
//使用随请求头的不同而变化的选项注册DbContext
services.AddDbContext((提供者、构建者)=>
{
//获取当前HttpContext
HttpContext=provider.GetRequiredService().HttpContext;
//获取相关标题
var headerValue=context.Request.Headers[“用户代理”].Single();
//基于头值创建相关的连接字符串,并配置要针对SQL Server运行的上下文
var connectionString=CreateConnectionString(headerValue);
使用SQLServer(connectionString);
});
///最安全的方法之一是DbContext不是线程安全的
清单项目;
等待使用(var_dataContext=newdatacontext(connectionString:“连接字符串”))
{
Boughts=wait_dataContext.YourModel.toListSync();
}

不同的连接字符串?是。我们必须使用相同的表和所有东西来设置2 DB。只是基于某些参数,数据必须发送到不同的实例@Schwarzie2478我想你需要两个DB上下文。(99%确定)如果模型没有您所做的所有更改,它将如何保持一致性?我不认为这是分离这些insert语句(您可能想要的)的最佳方法。在您的业务逻辑中或者在数据库级别(如果他们可以相互对话)执行此操作。@Schwarzie2478所以您的意思是我需要两个上下文类,Contextone和contexttwo?然后我在启动中注册这2个实例。然后在我的业务层,我必须注入这两个实例,并根据一些参数使用其中任何一个。是的,这也是我所想的。这是你用不同的模型所做的,但是它可以用在相同的模型和不同的连接字符串上…>你应该需要两个DBContext,是吗?这是什么意思?不,不需要两个不同的DbContext类来使用不同的连接字符串。这是一个解决方案,但远不是最好的。如果你能做到,那么就去做并帮助他。嗨,startup.cs中的“连接”是什么?services.AddDbContext(options=>options.UseSqlServer(connection));此连接不能为空,因为在“代码优先”方法中,“添加迁移”将失败。@RocketSigh您希望用于存储租户配置的任何数据库。但这并不是重要的部分-您可以使用任何类型的存储来存储租户数据。那你是在问多重所有权的问题吗?你应该更新这个问题并使之具体化让我试试你的建议。现在来看,问题是如何根据一些标准为每个请求传递不同的连接字符串。你应该删除这个,因为你已经发布了一个相关的答案
services.AddDbContext<TenantsContext>(options => options.UseSqlServer(connection));
services.AddScoped<ITenantProvider, WebTenantProvider>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
// needed below
services.AddHttpContextAccessor();

// register DbContext with options that change depending on request's header
services.AddDbContext<DatabaseContext>((provider, builder) =>
{
    // get current HttpContext
    HttpContext context = provider.GetRequiredService<IHttpContextAccessor>().HttpContext;

    // get relevant header
    var headerValue = context.Request.Headers["user-agent"].Single();

    // create relevant connection string based on header value and configure context to run against SQL Server
    var connectionString = CreateConnectionString(headerValue);
    builder.UseSqlServer(connectionString);
});
//// one of safest way as DbContext is not thread safe 
    List<Model> Items;
    await using (var _dataContext = new DataContext(connectionString:"connection String"))
    {
      Boughts = await _dataContext.YourModel.ToListAsync();
    }