繁体   English   中英

EF Core 和多个数据库

[英]EF Core and Multiple Databases

我有一个包含三个数据库的遗留系统

  1. 小贩
  2. 自定义代码
  3. 日志数据

供应商包含来自我们的供应商应用程序的控制和日志数据。

CustomCode 包含许多连接到 Vendor 和 LogData 的视图和存储过程

LogData 包含来自我们的 CustomCode 流程的结果。 例如:每日/每周/每月总结和结果。

我正在编写一个将在地图上绘制数据的网站。 单位列表来自 CustomCode 中的视图。 摘要记录来自 LogData,各个日志点通过 CustomCode 中的存储过程从 Vendor 检索。

我从 CustomCode 的 DbContext 开始,但似乎无法导航到第二个 DbContext 中的属性到 LogData

我可以在不同上下文中的对象之间链接导航属性吗?

我可以有一次连接多个数据库的上下文吗?

请注意,这与多租户或多模式无关

我可以在不同上下文中的对象之间链接导航属性吗?

不。

我可以有一个连接多个数据库的上下文吗?

不。

建议:

如果数据库可以相互通信(即在同一台服务器上),这似乎已经完成了

CustomCode 包含许多连接到 Vendor 和 LogData 的视图和存储过程

然后创建一个存储过程来执行所需的查询(可以连接来自不同数据库的表)。

从那里您应该能够从实体框架公开和执行过程以执行所需的功能。

这将避免有多个上下文并尝试将数据连接到内存中,如果数据集很大,这可能会产生不利影响。

在 EF Core 5.0 新功能中,现在可以更轻松地创建没有任何连接或连接字符串的 DbContext 实例。 此外,现在可以在上下文实例上更改连接或连接字符串。 此功能允许相同的上下文实例动态连接到不同的数据库。

参考: https : //docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-5.0/whatsnew#use-ac-attribute-to-indicate-that-an-entity-没有钥匙

不,您不能在不同上下文中的对象之间链接导航属性。 上下文表示特定的连接或数据库。 您可以尝试从多个上下文 (DB) 获取数据并加入它们并在内存中使用。

也在别处回答( https://stackoverflow.com/a/54347237/861352 ),但这里是要点:

这实际上似乎是一个已知问题,正在准备解决方案(尽管尚未确定优先级):

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

然而,我确实找到了这个问题的临时解决方案,它基于两个来源:

https://stackoverflow.com/a/26922902/861352(EF6解决方案) https://weblogs.asp.net/ricardoperes/interception-in-entity-framework-core

这是:


如何使用一个 EF Core DbContext 跨数据库连接(同一服务器)


您需要安装 Microsoft.Extensions.DiagnosticAdapter Nuget 包

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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM