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开始,但似乎无法
请注意,这与多租户或多架构无关。不,您不能在不同上下文中的对象之间链接导航属性。上下文表示特定的连接或数据库。您可以尝试从多个上下文(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)