在Entity Framework中的运行时期间更改数据库,而不更改Connection

时间:2021-12-03 16:25:27

I have a server that hosts 50 databases with identical schemas, and I want to start using Entity Framework in our next version.

我有一台服务器托管50个具有相同模式的数据库,我想在下一版本中开始使用Entity Framework。

I don't need a new connection for each of those databases. The privileges of the one connection can talk to all of the 50 databases, and for data management and speed (this is a WebAPI application) I don't want to instantiate a new EF context every time I talk to each of the databases if I don't have to, unless of course if this occurs each time a request comes to the server then no big deal.

我不需要为每个数据库建立新连接。一个连接的权限可以与所有50个数据库通信,并且对于数据管理和速度(这是一个WebAPI应用程序)我不希望每次与每个数据库通信时实例化新的EF上下文,如果我不必,除非当然每次请求到达服务器时都会发生这种情况,那就没什么大不了的。

All I really need is the ability to change the USE [databasename] command, which I assume eventually gets sent to the server from EF.

我真正需要的是能够更改USE [databasename]命令,我假设最终从EF发送到服务器。

Is there a way to accomplish this in code? Does EF maintain a read/write property in the Context that refers to the database name that could be changed on the fly before calling SaveChanges(), etc.??

有没有办法在代码中完成此操作? EF是否在Context中保持读/写属性,该属性引用可以在调用SaveChanges()等之前动态更改的数据库名称。

Thank you!!!

谢谢!!!

bob

短发

6 个解决方案

#1


2  

You can take a look at:

你可以看看:

  • SO question about passing existing SQL Connection to EntityFramework Context
  • 关于将现有SQL连接传递给EntityFramework Context的问题
  • and at this article describing how to change database on existing connection.
  • 在本文中描述如何在现有连接上更改数据库。

Please let me know if any additional help is needed.

如果需要任何其他帮助,请告诉我。

Edited
Updated 2nd link to point to SqlConnection.ChangeDatabase method.
So eventually code would look similarly to the following:

编辑更新了第二个链接以指向SqlConnection.ChangeDatabase方法。所以最终代码看起来与以下类似:

MetadataWorkspace workspace = new MetadataWorkspace(
  new string[] { "res://*/" }, 
  new Assembly[] { Assembly.GetExecutingAssembly() });

using (SqlConnection sqlConnection = new SqlConnection(connectionString))
using (EntityConnection entityConnection = new EntityConnection(workspace, sqlConnection))
using (NorthwindEntities context = new NorthwindEntities(entityConnection))
{
  // do whatever on default database
  foreach (var product in context.Products)
  {
    Console.WriteLine(product.ProductName);
  }

  // switch database
  sqlConnection.ChangeDatabase("Northwind");
  Console.WriteLine("Database: {0}", connection.Database);
}

#2


12  

Don't Work hard, work smart !!!!

不要努力工作,聪明地工作!!!!

MYContext localhostContext = new MYContext();
MYContext LiveContext = new MYContext();
//If your databases in different servers
LiveContext.Database.Connection.ConnectionString = LiveContext.Database.Connection.ConnectionString.Replace("localhost", "Live");
//If your databases have different Names
LiveContext.Database.Connection.ConnectionString = LiveContext.Database.Connection.ConnectionString.Replace("DBName-Localhost", "DBName-Live");

the structure for databases should be the same ;)

数据库的结构应该是相同的;)

#3


4  

It is very simple

这很简单

I had

我有

public WMSEntities() : base("name=WMSEntities") //WMSEntities is conection string name in web.config also the name of EntityFramework
{
}

already in autogenerated Model.Context.cs of edmx folder.

已经在自动生成的edmx文件夹的Model.Context.cs中。

To connect to multiple database in runtime, I created another constructor that takes connection string as parameter like below in same file Model.Context.cs

为了在运行时连接到多个数据库,我创建了另一个构造函数,它在同一个文件Model.Context.cs中将连接字符串作为参数如下所示

public WMSEntities(string connStringName)
            : base("name=" + connStringName)
{
}

Now, I added other connection string in Web.Config for example

现在,我在Web.Config中添加了其他连接字符串

<add name="WMSEntities31" connectionString="data source=TESTDBSERVER_NAME;initial catalog=TESTDB;userid=TestUser;password=TestUserPW/>

<add name="WMSEntities" connectionString="data source=TESTDBSERVER_NAME12;initial catalog=TESTDB12;userid=TestUser12;password=TestUserPW12/>

Then, when connecting to database I call below method passing connectionString name as parameter

然后,当连接到数据库时,我调用下面的方法传递connectionString名称作为参数

public static List<v_POVendor> GetPOVendorList(string connectionStringName)
{

   using (WMSEntities db = new WMSEntities(connectionStringName))
   {               
       vendorList = db.v_POVendor.ToList();
   }
}

#4


1  

Here's my solution for just changing the database name. Simply pull the string from the web or app.config file, modify it, and then instantiate:

这是我只更改数据库名称的解决方案。只需从web或app.config文件中提取字符串,修改它,然后实例化:

        string yourConnection = ConfigurationManager.ConnectionStrings["MyEntities"].ConnectionString.Replace("MyDatabase", yourDatabaseName);
        dcon = new MyEntities(yourConnection);

#5


0  

I have implemented this in my current project in which we have a common security database and different database for every client in the project. So our security database has a table that contain connection string for every other database. We just pass client id and get the connection string of the client database..

我在我当前的项目中实现了这一点,在该项目中,我们为项目中的每个客户端都有一个公共安全数据库和不同的数据库因此,我们的安全数据库有一个包含每个其他数据库的连接字符串的表。我们只传递客户端ID并获取客户端数据库的连接字符串。

For this add two EDMX one for the common database and other for common schema databases. When user login or what might be your scenario to choose database go to common databse and get the connection string and create object of the needed database. Here is Code sample any, if any quer let me know..

为此,为公共数据库添加两个EDMX,为通用模式数据库添加另一个EDMX。当用户登录或可能是您选择数据库的场景时,请转到常用数据库并获取连接字符串并创建所需数据库的对象。这里是Code sample any,如果有任何查询让我知道..

You can keep connection string regarding every other database in a table in a a common database shared by all the other database.

您可以保留关于所有其他数据库共享的公共数据库中的表中的每个其他数据库的连接字符串。

EntityInstance_ReviewEntities.GetContext(GetConnectionString(ClientId));


private string GetConnectionString(int TenantId)
        {
            EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();
            ISecurityRepository objSecurity = new SecurityRepository();
            string tenantConnectionString = objSecurity.GetClientConnectionString(TenantId);
            entityBuilder.ProviderConnectionString = tenantConnectionString;
            entityBuilder.Provider = "System.Data.SqlClient";
            entityBuilder.Metadata = @"res://*/ClientEntity.YourEntity.csdl|res://*/ClientEntity.ADBClientEntity.ssdl|res://*/ClientEntity.YourEntity.msl";
            return entityBuilder.ToString();
        }

#6


0  

EntityConnection.ChangeDatabase method is not supported, but SqlConnection.ChangeDatabase works fine.

不支持EntityConnection.ChangeDatabase方法,但SqlConnection.ChangeDatabase工作正常。

So you have to use SqlConnection in entity framework database's constructor:

所以你必须在实体框架数据库的构造函数中使用SqlConnection:

using MvcMyDefaultDatabase.Models;
using System.Data.Metadata.Edm;
using System.Data.SqlClient;
using System.Data.EntityClient;
using System.Configuration;
using System.Reflection;

    public ActionResult List(string Schema)
    {
        SqlConnection sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);

        MetadataWorkspace workspace = new MetadataWorkspace(new string[] { "res://*/" }, new Assembly[] { Assembly.GetExecutingAssembly() });

        EntityConnection entityConnection = new EntityConnection(workspace, sqlConnection);

        sqlConnection.Open();

        sqlConnection.ChangeDatabase(Schema);

        Models.MyEntities db = new MyEntities(entityConnection);

        List<MyTableRecords> MyTableRecordsList = db.MyTableRecords.ToList();

        return View(MyTableRecordsList);
    }

With this code you can read the tables with the same format (same table name and same fields) of several schema passing the database name in the "Schema" string.

使用此代码,您可以读取具有相同格式(相同的表名和相同字段)的表,这些模式在“Schema”字符串中传递数据库名称。

#1


2  

You can take a look at:

你可以看看:

  • SO question about passing existing SQL Connection to EntityFramework Context
  • 关于将现有SQL连接传递给EntityFramework Context的问题
  • and at this article describing how to change database on existing connection.
  • 在本文中描述如何在现有连接上更改数据库。

Please let me know if any additional help is needed.

如果需要任何其他帮助,请告诉我。

Edited
Updated 2nd link to point to SqlConnection.ChangeDatabase method.
So eventually code would look similarly to the following:

编辑更新了第二个链接以指向SqlConnection.ChangeDatabase方法。所以最终代码看起来与以下类似:

MetadataWorkspace workspace = new MetadataWorkspace(
  new string[] { "res://*/" }, 
  new Assembly[] { Assembly.GetExecutingAssembly() });

using (SqlConnection sqlConnection = new SqlConnection(connectionString))
using (EntityConnection entityConnection = new EntityConnection(workspace, sqlConnection))
using (NorthwindEntities context = new NorthwindEntities(entityConnection))
{
  // do whatever on default database
  foreach (var product in context.Products)
  {
    Console.WriteLine(product.ProductName);
  }

  // switch database
  sqlConnection.ChangeDatabase("Northwind");
  Console.WriteLine("Database: {0}", connection.Database);
}

#2


12  

Don't Work hard, work smart !!!!

不要努力工作,聪明地工作!!!!

MYContext localhostContext = new MYContext();
MYContext LiveContext = new MYContext();
//If your databases in different servers
LiveContext.Database.Connection.ConnectionString = LiveContext.Database.Connection.ConnectionString.Replace("localhost", "Live");
//If your databases have different Names
LiveContext.Database.Connection.ConnectionString = LiveContext.Database.Connection.ConnectionString.Replace("DBName-Localhost", "DBName-Live");

the structure for databases should be the same ;)

数据库的结构应该是相同的;)

#3


4  

It is very simple

这很简单

I had

我有

public WMSEntities() : base("name=WMSEntities") //WMSEntities is conection string name in web.config also the name of EntityFramework
{
}

already in autogenerated Model.Context.cs of edmx folder.

已经在自动生成的edmx文件夹的Model.Context.cs中。

To connect to multiple database in runtime, I created another constructor that takes connection string as parameter like below in same file Model.Context.cs

为了在运行时连接到多个数据库,我创建了另一个构造函数,它在同一个文件Model.Context.cs中将连接字符串作为参数如下所示

public WMSEntities(string connStringName)
            : base("name=" + connStringName)
{
}

Now, I added other connection string in Web.Config for example

现在,我在Web.Config中添加了其他连接字符串

<add name="WMSEntities31" connectionString="data source=TESTDBSERVER_NAME;initial catalog=TESTDB;userid=TestUser;password=TestUserPW/>

<add name="WMSEntities" connectionString="data source=TESTDBSERVER_NAME12;initial catalog=TESTDB12;userid=TestUser12;password=TestUserPW12/>

Then, when connecting to database I call below method passing connectionString name as parameter

然后,当连接到数据库时,我调用下面的方法传递connectionString名称作为参数

public static List<v_POVendor> GetPOVendorList(string connectionStringName)
{

   using (WMSEntities db = new WMSEntities(connectionStringName))
   {               
       vendorList = db.v_POVendor.ToList();
   }
}

#4


1  

Here's my solution for just changing the database name. Simply pull the string from the web or app.config file, modify it, and then instantiate:

这是我只更改数据库名称的解决方案。只需从web或app.config文件中提取字符串,修改它,然后实例化:

        string yourConnection = ConfigurationManager.ConnectionStrings["MyEntities"].ConnectionString.Replace("MyDatabase", yourDatabaseName);
        dcon = new MyEntities(yourConnection);

#5


0  

I have implemented this in my current project in which we have a common security database and different database for every client in the project. So our security database has a table that contain connection string for every other database. We just pass client id and get the connection string of the client database..

我在我当前的项目中实现了这一点,在该项目中,我们为项目中的每个客户端都有一个公共安全数据库和不同的数据库因此,我们的安全数据库有一个包含每个其他数据库的连接字符串的表。我们只传递客户端ID并获取客户端数据库的连接字符串。

For this add two EDMX one for the common database and other for common schema databases. When user login or what might be your scenario to choose database go to common databse and get the connection string and create object of the needed database. Here is Code sample any, if any quer let me know..

为此,为公共数据库添加两个EDMX,为通用模式数据库添加另一个EDMX。当用户登录或可能是您选择数据库的场景时,请转到常用数据库并获取连接字符串并创建所需数据库的对象。这里是Code sample any,如果有任何查询让我知道..

You can keep connection string regarding every other database in a table in a a common database shared by all the other database.

您可以保留关于所有其他数据库共享的公共数据库中的表中的每个其他数据库的连接字符串。

EntityInstance_ReviewEntities.GetContext(GetConnectionString(ClientId));


private string GetConnectionString(int TenantId)
        {
            EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();
            ISecurityRepository objSecurity = new SecurityRepository();
            string tenantConnectionString = objSecurity.GetClientConnectionString(TenantId);
            entityBuilder.ProviderConnectionString = tenantConnectionString;
            entityBuilder.Provider = "System.Data.SqlClient";
            entityBuilder.Metadata = @"res://*/ClientEntity.YourEntity.csdl|res://*/ClientEntity.ADBClientEntity.ssdl|res://*/ClientEntity.YourEntity.msl";
            return entityBuilder.ToString();
        }

#6


0  

EntityConnection.ChangeDatabase method is not supported, but SqlConnection.ChangeDatabase works fine.

不支持EntityConnection.ChangeDatabase方法,但SqlConnection.ChangeDatabase工作正常。

So you have to use SqlConnection in entity framework database's constructor:

所以你必须在实体框架数据库的构造函数中使用SqlConnection:

using MvcMyDefaultDatabase.Models;
using System.Data.Metadata.Edm;
using System.Data.SqlClient;
using System.Data.EntityClient;
using System.Configuration;
using System.Reflection;

    public ActionResult List(string Schema)
    {
        SqlConnection sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);

        MetadataWorkspace workspace = new MetadataWorkspace(new string[] { "res://*/" }, new Assembly[] { Assembly.GetExecutingAssembly() });

        EntityConnection entityConnection = new EntityConnection(workspace, sqlConnection);

        sqlConnection.Open();

        sqlConnection.ChangeDatabase(Schema);

        Models.MyEntities db = new MyEntities(entityConnection);

        List<MyTableRecords> MyTableRecordsList = db.MyTableRecords.ToList();

        return View(MyTableRecordsList);
    }

With this code you can read the tables with the same format (same table name and same fields) of several schema passing the database name in the "Schema" string.

使用此代码,您可以读取具有相同格式(相同的表名和相同字段)的表,这些模式在“Schema”字符串中传递数据库名称。