EF核心和多个数据库

时间:2018-09-03 23:52:12

标签: c# asp.net-core entity-framework-core

我有一个具有三个数据库的旧系统

  1. 供应商
  2. CustomCode
  3. LogData

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

CustomCode包含许多视图和存储过程,这些视图和存储过程已连接到Vendor和LogData

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

我正在写一个网站,将数据绘制在地图上。单位列表来自CustomCode中的视图。摘要记录来自LogData,而单个日志点则通过CustomCode中存储的proc从供应商处检索。

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

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

我可以一次连接多个数据库吗?

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

4 个答案:

答案 0 :(得分:3)

  

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

否。

  

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

否。

建议:

如果数据库之间可以相互通信(即同一服务器上的 ),那么自

开始,这似乎已经完成
  

CustomCode包含许多视图和存储过程,这些视图和存储过程已连接到Vendor和LogData

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

从那里,您应该能够从Entity Framework公开并执行该过程以执行所需的功能。

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

答案 1 :(得分:1)

在EF Core 5.0的新功能中,现在更容易创建没有任何连接或连接字符串的DbContext实例。而且,现在可以在上下文实例上对连接或连接字符串进行突变。此功能允许同一上下文实例动态连接到不同的数据库。

参考: https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-5.0/whatsnew#use-a-c-attribute-to-indicate-that-an-entity-has-no-key

答案 2 :(得分:0)

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

答案 3 :(得分:0)

也回答了其他问题(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”和“用户”,也许可以通过配置等代替。

然后将该拦截器附加到您的上下文中。

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)