EF Core и несколько баз данных
У меня есть устаревшая система с тремя базами данных
- продавец
- Пользовательский код
- 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
Надеюсь, поможет!