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

时间:2013-09-17 04:09:29

标签: c# sql-server entity-framework asp.net-web-api

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

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

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

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

谢谢!!!

鲍勃

7 个答案:

答案 0 :(得分:13)

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

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");

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

答案 1 :(得分:4)

非常简单

我有

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

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

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

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

现在,我在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/>

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

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

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

答案 2 :(得分:2)

你可以看看:

  • SO question关于将现有SQL连接传递给 EntityFramework上下文
  • this article描述如何 在现有连接上更改数据库。

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

<强>被修改
更新了第二个链接以指向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);
}

答案 3 :(得分:1)

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

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

答案 4 :(得分:0)

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

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

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

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();
        }

答案 5 :(得分:0)

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

所以你必须在实体框架数据库的构造函数中使用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);
    }

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

答案 6 :(得分:0)

对于 SQL Server,如果您只想更改数据库,而不是连接,请尝试:

public class XXXXDbContext : DbContext
{

    public string databaseName
    {
        set
        {
            Database.GetDbConnection().Open();
            Database.GetDbConnection().ChangeDatabase(value);
        }
    }
}