Измените базу данных во время выполнения в Entity Framework, не меняя Connection

У меня есть сервер, на котором размещаются 50 баз данных с одинаковыми схемами, и я хочу начать использовать Entity Framework в нашей следующей версии.

Мне не нужно новое соединение для каждой из этих баз данных. Привилегии одного соединения могут разговаривать со всеми из 50 баз данных, а также для управления данными и скорости (это приложение WebAPI). Я не хочу создавать экземпляр нового EF-контекста каждый раз, когда я общаюсь с каждой из баз данных, если я не нужно, если, конечно, если это происходит каждый раз, когда запрос поступает на сервер, тогда нет большой сделки.

Мне действительно нужна возможность изменить команду USE [databasename], которая, как я полагаю, в конечном итоге будет отправлена ​​на сервер из EF.

Есть ли способ сделать это в коде? Поддерживает ли EF свойство чтения/записи в Контексте, которое ссылается на имя базы данных, которое может быть изменено "на лету" перед вызовом SaveChanges() и т.д.

Спасибо!!!

боб

Ответ 1

Вы можете взглянуть на:

  • Вопрос SO о передаче существующего подключения SQL к Контекст EntityFramework
  • и в этой статье, описывающей, как изменить базу данных на существующее соединение.

Пожалуйста, дайте мне знать, нужна ли какая-либо дополнительная помощь.

Edited
Обновлена ​​2-я ссылка, чтобы указать на 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

Не работай, работай умный!!!!

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

структура баз данных должна быть одинаковой;)

Ответ 3

Это очень просто

У меня был

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

уже в Autogenerated Model.Context.cs папки edmx.

Чтобы подключиться к нескольким базам данных во время выполнения, я создал другой конструктор, который принимает строку подключения как параметр, как показано ниже в том же файле Model.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();
   }
}

Ответ 4

Здесь мое решение для простого изменения имени базы данных. Просто вытащите строку из Интернета или файла app.config, измените ее, а затем создайте экземпляр:

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

Ответ 5

Я реализовал это в своем текущем проекте, в котором у нас есть общая база данных безопасности и разные базы данных для каждого клиента в проекте. Таким образом, наша база данных безопасности содержит таблицу, содержащую строку подключения для каждой другой базы данных. Мы просто передаем идентификатор клиента и получаем строку подключения клиентской базы данных.

Для этого добавьте два EDMX для общей базы данных и других для общих баз данных схемы. Когда пользовательский логин или какой может быть ваш сценарий для выбора базы данных, перейдите в общую базу данных и получите строку подключения и создайте объект необходимой базы данных. Вот пример кода 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();
        }

Ответ 6

Метод 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);
    }

С помощью этого кода вы можете читать таблицы с одинаковым форматом (одно и то же имя таблицы и одинаковые поля) нескольких схем, передающих имя базы данных в строке "Схема".