所以提问者 (P.Joe) 在这里回答了他自己的问题 (https://stackoverflow.com/a/43326729/861352),但我实际上无法得到这个答案。它不起作用的原因是
[Table("dbname.scheme.Stock", Schema = "dbo")]
将在 sql 中呈现为
[dbo].[dbname.scheme.Stock]
什么时候你真正想要的 SQL 是
[dbname].[dbo].[Stock]
即使您尝试弄乱它也行不通。我尝试了各种组合
[Table("Stock", Schema = "dbname.dbo")] // SQL => [dbname.dbo].[Stock]
[Table("Stock", Schema = "[dbname].[dbo]")] // SQL => [[dbname]].[dbo]]].[Stock]
[Table("Stock", Schema = "dbname].[dbo")] // SQL => [dbname]].[dbo].[Stock]
[Table("Stock", Schema = "dbname.[dbo")] // SQL => [dbname.[dbo].[Stock]
...等等。基本问题是您需要将 dbname 与在解析时转义的括号分开。
这实际上似乎是一个已知问题,正在制定解决方案(尽管尚未确定优先级):
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 进行(同一服务器)跨 DB 联接
您需要安装 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 = "Stock";
command.CommandText = command.CommandText.Replace($" [{tableName}]", $" [{schemaName}].[{tableName}]")
.Replace($" [{schemaName}].[{tableName}]", $" [{secondaryDatabaseName}].[{schemaName}].[{tableName}]");
}
}
}
用您的数据库名称、表架构和表名替换“MyOtherDatabase”、“dbo”和“Stock”,可能来自配置等。
然后将该拦截器附加到您的上下文中。
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.Stocks // MyOtherDatabase (a different database on the same server)