Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF核心和多个数据库_C#_Asp.net Core_Entity Framework Core - Fatal编程技术网

C# EF核心和多个数据库

C# EF核心和多个数据库,c#,asp.net-core,entity-framework-core,C#,Asp.net Core,Entity Framework Core,我有一个带有三个数据库的遗留系统 卖主 海关编码 日志数据 供应商包含来自我们供应商应用程序的控制和日志数据 CustomCode包含许多视图和存储过程,它们连接到供应商和日志数据 LogData包含来自我们CustomCode流程的结果。例:每日/每周/每月总结和结果 我正在写一个网站,将数据绘制在地图上。单位列表来自CustomCode中的视图。摘要记录来自LogData,单个日志点由CustomCode中存储的过程从供应商处检索 我从CustomCode的DbContext开始,但似乎无法

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

  • 卖主
  • 海关编码
  • 日志数据
  • 供应商包含来自我们供应商应用程序的控制和日志数据

    CustomCode包含许多视图和存储过程,它们连接到供应商和日志数据

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

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

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

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

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


    请注意,这与多租户或多架构无关。不,您不能在不同上下文中的对象之间链接导航属性。上下文表示特定的连接或数据库。您可以尝试从多个上下文(DBs)获取数据,并将它们连接起来并在内存中使用

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

    没有

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

    没有

    建议:


    如果数据库可以相互通信(即在同一台服务器上),则自

    CustomCode包含许多视图和存储过程,它们连接到供应商和日志数据

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

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

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

    在别处也有回答(),但要点如下:

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

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

    (EF6解决方案)

    这是:


    如何使用一个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;
    
    

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


    参考:

    我能否在不同上下文中链接对象之间的导航属性,我认为这是不可能的。。最好是创建一个助手方法或其他东西。。我认为连接间的字符串关系非常危险(没有人能保证这种关系,但是你的代码)…不,每个上下文代表一个不同的连接,你不能这样做。EF不是为此用例设计的。您必须从每个上下文加载数据,然后连接内存。如果数据库可以相互通信(即在同一台服务器上),则创建一个存储过程以执行所需的查询(可以连接来自不同数据库的表)从这里开始,您应该能够执行过程表单EF。您是否愿意发布一个我可以(遗憾地)接受的答案?唯一的问题是,将sp加载到DbQuery而不是DbSet中意味着我不能将它们用作导航属性的权威实体。我可以使用更多的单片sp,但呃。EF给予,它带走;)我认为这是一个肮脏的解决方案,不太可靠。在一个事务中写入不同的数据库可能是一个障碍。一个不那么肮脏(但仍然不健全)的解决方案是“使用同义词”。@GertArnold我没有说这是一个理想的解决方案,我说这是一个临时解决方案,因为他们正确地解决了问题,如前所述。上面的解决方案已经使用基本的读、写和交叉数据库连接进行了测试,到目前为止,我的使用情况还不错。如果您有更好的使用同义词的解决方案,请发布完整的答案。如果数据库位于不同的服务器上会怎么样?这让我想到。。在我的例子中,它们是同一个数据库,所以也许我应该使用新的标识表来连接我的旧表,即使它们在不同的上下文中,因为数据库首先是数据库,身份信息首先是模型。你应该提供一个例子,说明在EF Core 5.0中是如何做到这一点的——我敢打赌这会给你带来很多选票。
    
    var context = new MultipleDatabasesExampleDbContext(optionsBuilder.Options);
    
    // Add interceptor to switch between databases
    var listener = context.GetService<DiagnosticSource>();
    (listener as DiagnosticListener).SubscribeWithAdapter(new CommandInterceptor());
    
    
    context.Customers // Default database defined in connection string
    context.Users     // MyOtherDatabase (a different database on the same server)