首页 > 解决方案 > 如何在运行时使用 EF 和 Structuremap 更改连接字符串?

问题描述

我正在.net MVC Web 应用程序中开发,我正在使用 EF(DB FIRST) 来获取数据:

    public class LocationManager: MyNetworkEntities,  ILocationManager
    {
        private readonly MyNetworkEntities _dbContext = new MyNetworkEntities();

        public LocationManager(MyNetworkEntities context, string connection)
        {
            // extension for changing connectionstring at runtime
            if(connection != null)
            context.ChangeDatabase
                    (
                        dataSource: connection 
                    );


        _dbContext = context;
    }

    public List<Locations> GetAll()
    {
        return _dbContext.Locations.ToList();
    }
}

还使用结构图:

public DefaultRegistry() {
    Scan(
        scan => {
            scan.TheCallingAssembly();
            scan.WithDefaultConventions();
            scan.With(new ControllerConvention());
        });
    For<ILocationManager>().Use<LocationManager>();
}

我的控制器:

public class UserController : Controller
{
    private readonly ILocationManager _locationManager;

    public UserController(ILocationManager locationManager)
    {
        _locationManager = locationManager;
    }
    // GET: User
    public ActionResult Index()
    {
        var t = _locationManager.GetAll();
        return View("UserManagment");
    }
}

问题:

由于我想在运行时更改 db-connectionstring,所以在使用结构映射时我将如何做到这一点?

就像是:

string myNewConnection = "connection";
 var t = _locationManager.setConnection(myNewConnection).GetAll();

我将如何做到这一点?

注意:上面的代码不完整,我还在努力解决这个问题。

标签: c#asp.net-mvcentity-frameworkstructuremap

解决方案


我猜你的EF Core DbContext样子是这样的:

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

在这种情况下,您可以只创建您的DbContext(您不必在DI任何地方使用)并将其指向您需要的数据库:

var connectionString = ...
var builder = new DbContextOptionsBuilder<MyDbContext>().UseSqlServer(connectionString);
var context = new MyDbContext(builder.Options);
var locations = context.Locations.ToList();

当然,您可以实现更复杂的东西,例如创建 DbContext 指向您需要的位置的工厂类,并DI通过构造函数注入机制来注册该工厂以获取它。工厂将有一些方法,如:

// This is a pseudo code below
factory.CreateDbContext (.. some parameters to detect which DB to use ..)

推荐阅读