在实体框架中动态更改数据库相同的方案

时间:2017-12-26 15:20:26

标签: c# entity-framework

我有一个上下文,我派生我的实体我有5个数据库,这些数据库不同于我需要在运行时切换的相同方案。用户将在启动应用程序时选择要连接的数据库。

具有相同方案的数据库是SMBASchedulerEntities,它只是不同的目录名称

public class SourceContext : ContextBase
{
    public SMBASchedulerEntities _sourceEntities = new SMBASchedulerEntities();
    public SystemDa _systemDB = new SystemDa();

    public void AddToPatient(Patient newPatient)
    {
        _sourceEntities.Patients.Add(newPatient);
        SaveChanges();
    }

    public void AddToAppointmentTypes(AppointmentType AppointmentTypes)
    {
        _sourceEntities.AppointmentTypes.Add(AppointmentTypes);
        SaveChanges();
    }
}

正如你所看到的那样,我在我的上下文中引用了实体,所以我希望有一个我可以调用的属性,例如changeDatabase,并且如果没有重新启动应用程序就会生效。

1 个答案:

答案 0 :(得分:1)

在实例化DbContext时,您可以传递要连接的连接字符串的名称。首先,你声明你的DbContext如此:

public class SMBASchedulerEntities : DbContext
{
    public SMBASchedulerEntities(string connectionString): base(connectionString)
    {

    }
}

您将所有连接字符串保留在Web.configApp.config中(取决于项目类型):

<connectionStrings>
    <add name="DefaultConnection1" connectionString="server=localhost;user id=MyAppUser;password=SecretPass;database=MyDatabase1" providerName="System.Data.SqlClient" />
    <add name="DefaultConnection2" connectionString="server=localhost;user id=MyAppUser;password=SecretPass;database=MyDatabase2" providerName="System.Data.SqlClient" />
    <add name="DefaultConnection3" connectionString="server=localhost;user id=MyAppUser;password=SecretPass;database=MyDatabase3" providerName="System.Data.SqlClient" />
    <add name="DefaultConnection4" connectionString="server=localhost;user id=MyAppUser;password=SecretPass;database=MyDatabase4" providerName="System.Data.SqlClient" />
    <add name="DefaultConnection5" connectionString="server=localhost;user id=MyAppUser;password=SecretPass;database=MyDatabase5" providerName="System.Data.SqlClient" />
</connectionStrings>

然后你就这样使用它:

using (var db = new SMBASchedulerEntities("DefaultConnection1"))
{
    // use MyDatabase1 through connection string "DefaultConnection1"
}

using (var db = new SMBASchedulerEntities("DefaultConnection2"))
{
    // use MyDatabase2 through connection string "DefaultConnection2"
}

处理您的DbContext

建议在使用后处置DbContext。如果您仍想将您的想法用于SourceContext,则可以实现以下内容:

public class SourceContext : ContextBase, IDisposable
{
    public SMBASchedulerEntities _sourceEntities;
    public SystemDa _systemDB = new SystemDa();

    public SourceContext(string connectionString)
    {
        _sourceEntities = new SMBASchedulerEntities(connectionString);
    }

    public void AddToPatient(Patient newPatient)
    {
        _sourceEntities.Patients.Add(newPatient);
        SaveChanges();
    }

    public void ChangeDatabaseTo(string connectionString)
    {
        if (_sourceEntities != null)
            _sourceEntities.Dispose();
        _sourceEntities = new SMBASchedulerEntities(connectionString);
    }

    public void AddToAppointmentTypes(AppointmentType AppointmentTypes)
    {
        _sourceEntities.AppointmentTypes.Add(AppointmentTypes);
        SaveChanges();


    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (_sourceEntities != null)
            {
                _sourceEntities.Dispose();
            }
        }
    }

}

...然后最终像这样使用它:

using(var context = new SourceContext("DefaultConnection1"))
{
    context.AddPatient(patient); // add to Database1

    context.ChangeDatabaseTo("DefaultConnection2");

    context.AddPatient(patient); // add to Database2

    context.ChangeDatabaseTo("DefaultConnection4");

    context.AddPatient(patient); // add to Database4
}

通过使SourceContext成为IDisposable,您有机会正确处置DbContext实例。请注意,我在更改之前已经处理了现有的DbContext