EF Core и несколько баз данных

У меня есть устаревшая система с тремя базами данных

  1. продавец
  2. Пользовательский код
  3. LogData

Vendor содержит данные управления и регистрации из нашего приложения Vendors.

CustomCode содержит множество представлений и хранимых процедур, которые соединяются с Vendor и LogData.

LogData содержит результаты наших процессов CustomCode. Например: Ежедневные / Еженедельные / Ежемесячные сводки и результаты.

Я пишу веб-сайт, который будет отображать данные на карте. Список единиц из представления в CustomCode. Сводная запись получена из LogData, а отдельные точки журнала извлекаются из Vendor с помощью сохраненного процесса в CustomCode.

Я начал с DbContext для CustomCode, но не могу перейти к свойствам во втором DbContext для LogData

Можно ли связать свойства навигации между объектами в разных контекстах?

Могу ли я иметь один раз контекст с несколькими подключенными базами данных?

Обратите внимание, что это не имеет ничего общего с мультитенантной или мульти-схемой

3 ответа

Решение

Можно ли связать свойства навигации между объектами в разных контекстах?

Нет.

Могу ли я иметь один контекст с несколькими подключенными базами данных?

Нет.

Предложение:

Если базы данных могут связываться друг с другом (т.е. на одном сервере), что, как представляется, уже сделано с

CustomCode содержит множество представлений и хранимых процедур, которые соединяются с Vendor и LogData.

затем создайте хранимую процедуру для выполнения желаемых запросов (которые могут объединять таблицы из отдельных баз данных).

Оттуда вы должны быть в состоянии выставить и выполнить процедуру из Entity Framework для выполнения желаемой функциональности.

Это позволит избежать нескольких контекстов и попыток объединения данных в памяти, что может иметь неблагоприятные последствия, если набор данных большой.

В новых функциях EF Core 5.0 теперь проще создать экземпляр DbContext без подключения или строки подключения. Кроме того, теперь можно изменять строку подключения или строку подключения в экземпляре контекста. Эта функция позволяет одному и тому же экземпляру контекста динамически подключаться к разным базам данных.

Ссылка: https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-5.0/whatsnew

Также ответил в другом месте ( /questions/44219329/vyipolnenie-proektsij-dlya-neskolkih-baz-dannyih-tolko-s-odnim-dbcontext/44219349#44219349), но вот суть:

На самом деле это, кажется, известная проблема, решение которой находится на стадии разработки (хотя она еще не была расставлена ​​по приоритетам):

https://github.com/aspnet/EntityFrameworkCore/issues/4019

Однако я нашел временное решение этой проблемы, и оно основано на двух источниках:

/questions/33696621/kross-zaprosyi-k-baze-dannyih-v-ef/33696650#33696650 (решение EF6) https://weblogs.asp.net/ricardoperes/interception-in-entity-framework-core

И вот оно:


Как сделать (тот же сервер) Cross DB объединяется с одним EF Core DbContext


Вам нужно будет установить пакет Nuget Microsoft.Extensions.DiagnosticAdapter

using System;
using System.Data.Common;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.DiagnosticAdapter;

namespace Example
{
    public class CommandInterceptor
    {
        [DiagnosticName("Microsoft.EntityFrameworkCore.Database.Command.CommandExecuting")]
        public void OnCommandExecuting(DbCommand command, DbCommandMethod executeMethod, Guid commandId, Guid connectionId, bool async, DateTimeOffset startTime)
        {
            var secondaryDatabaseName = "MyOtherDatabase";
            var schemaName = "dbo";
            var tableName = "Users";

            command.CommandText = command.CommandText.Replace($" [{tableName}]", $" [{schemaName}].[{tableName}]")
                                                     .Replace($" [{schemaName}].[{tableName}]", $" [{secondaryDatabaseName}].[{schemaName}].[{tableName}]");
        }
    }
}

Замените "MyOtherDatabase", "dbo" и "Users" на имя вашей базы данных, схему таблицы и имя таблицы, возможно из конфигурации и т. Д.

Затем прикрепите этот перехватчик к вашему контексту.

using System.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;


var context = new MultipleDatabasesExampleDbContext(optionsBuilder.Options);

// Add interceptor to switch between databases
var listener = context.GetService<DiagnosticSource>();
(listener as DiagnosticListener).SubscribeWithAdapter(new CommandInterceptor());

В моем случае я положил выше в метод MultipleDatabasesExampleDbContextFactory.

Теперь вы можете просто использовать контекст, как если бы вы ссылались на одну базу данных.

context.Customers // Default database defined in connection string
context.Users     // MyOtherDatabase (a different database on the same server)

Нет, вы не можете связать свойства навигации между объектами в разных контекстах. Контекст представляет собой конкретное соединение или БД. Вы можете попытаться получить данные из нескольких контекстов (БД), объединить их и использовать в памяти.

Вы должны посмотреть здесь. Я еще не тестировал его, но я рассматриваю возможность его реализации, поскольку у меня есть устаревшая база данных с 23 базами данных, которые мне нужно запрашивать.

https://github.com/laskoviymishka/EntityFramework/commit/2beffadec1671b8b4935b0c3eeb41d47890f9047

Надеюсь, поможет!

Другие вопросы по тегам