在运行时创建Dbcontext [英] Create Dbcontext at run-time

查看:92
本文介绍了在运行时创建Dbcontext的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在运行时切换到其他数据源.有时,用户希望连接到其他数据库服务器来处理数据.可以有100多个具有相同数据库的客户端服务器.原始项目是.net核心Web API,服务器名称是输入参数.

这就是我的想法.有更好的选择吗?

 公共类Person{public int ID {get;放;}公共字符串名称{get;放;}}公共类MyDbContext:DbContext{公共MyDbContext(DbContextOptions< MyDbContext>选项):基本(选项){}公共DbSet< Person>人{放;}受保护的重写void OnModelCreating(ModelBuilder modelBuilder){modelBuilder.Entity< Person>().HasKey(a => a.Id);}}类程序:IDesignTimeDbContextFactory< MyDbContext>{静态异步任务Main(string [] args){var _context = new Program().CreateDbContext();//交易一会儿(true){var server_name = Console.ReadLine();如果(server_name =="exit")休息;string [] remoteServer = {server_name};//新的上下文使用var dbContextRemote = new Program().CreateDbContext(remoteServer);尝试{dbContextRemote.Database.BeginTransaction();var结果=等待dbContextRemote.Persons.FindAsync(1);//...//可以设置查询Console.WriteLine(result?.Name);//如果所有命令都成功提交事务,则事务将自动回滚dbContextRemote.Database.CommitTransaction();}抓住(前例外){Console.WriteLine(ex);//dbContextRemote.Database.RollbackTransaction();休息;}_context.Database.CloseConnection();}}公共MyDbContext CreateDbContext(string [] args = null){if(args == null || args.Length == 0)args = new string [] {"localhost"};var optionsBuilder = new DbContextOptionsBuilder< MyDbContext>();optionsBuilder.UseSqlServer($"Server = {args [0]}; Database = SampleDb; Trusted_Connection = True");返回新的MyDbContext(optionsBuilder.Options);}} 

解决方案

如果您正在使用 AddDbContext 调用注册数据库,则可以利用它的重载,从而可以访问 <代码>的IServiceProvider :

  public void ConfigureServices(IServiceCollection服务){服务.AddEntityFrameworkSqlServer().AddDbContext< MyContext>(((serviceProvider,options)=>{var connectionString = serviceProvider.GetService//获取服务//可以根据您的逻辑确定所需的连接字符串.GetConnectionString();options.UseSqlServer(connectionString);});}} 

此处使用Autofac可以实现类似的效果.>

I have a requirement to switch to a different data sources at runtime. sometimes user wants to connect to a different database server to manipulate data. There can be more than 100 client servers with an identical database. Original project is a .net core Web API and the server name is an input parameter.

This is what I thought. Is there a better alternative?

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class MyDbContext : DbContext
{
    public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
    {
    }

    public DbSet<Person> Persons { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Person>().HasKey(a => a.Id);

    }
}
class Program : IDesignTimeDbContextFactory<MyDbContext>
    {
        static async Task Main(string[] args)
        {
            var _context = new Program().CreateDbContext();
            //transactions
            while (true)
            {
                var server_name = Console.ReadLine();
                if (server_name == "exit")
                    break;
                string[] remoteServer = { server_name };

                //new context
                using var dbContextRemote = new Program().CreateDbContext(remoteServer);

                try
                {
                    dbContextRemote.Database.BeginTransaction();

                    var result = await dbContextRemote.Persons.FindAsync(1);
                    //.....
                    //can be set of queries
                    Console.WriteLine(result?.Name);

                    // Commit transaction if all commands succeed, transaction will auto-rollback
                    dbContextRemote.Database.CommitTransaction();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    //dbContextRemote.Database.RollbackTransaction();
                    break;
                }
                _context.Database.CloseConnection();
            }

        }
        public MyDbContext CreateDbContext(string[] args = null)
        {
            if (args == null || args.Length == 0)
                args = new string[] { "localhost" };

            var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
            optionsBuilder.UseSqlServer($"Server={args[0]};Database=SampleDb;Trusted_Connection=True");
            return new MyDbContext(optionsBuilder.Options);
        }
    }

解决方案

If you are registering your DB with AddDbContext call you can leverage it's overload which provides you access to IServiceProvider:

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddEntityFrameworkSqlServer()
        .AddDbContext<MyContext>((serviceProvider, options) =>
        {
             var connectionString = serviceProvider.GetService // get your service 
             // which can determine needed connection string based on your logic
             .GetConnectionString();
              options.UseSqlServer(connectionString);
         });
       }
}

Also here something similar is achieved with Autofac.

这篇关于在运行时创建Dbcontext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆