Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.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# 仅使用一个dbContext在多个数据库上执行投影_C#_Database_Entity Framework - Fatal编程技术网

C# 仅使用一个dbContext在多个数据库上执行投影

C# 仅使用一个dbContext在多个数据库上执行投影,c#,database,entity-framework,C#,Database,Entity Framework,我们正在为当前项目使用EF.Core。该项目有三个数据库,这真是一个无法避免的麻烦。这些数据库具有相同的结构。因此,我们能够交换上下文并使用相同的EF模型来执行CRUD操作 我们将从传统的ADO.NET原始SQL移植一个特别复杂的查询。问题是它是一个跨数据库查询。要复制这个问题,我们真正需要的是一种方法,从同一dbContext中的三个数据库中获取所讨论查询的所有三个表 绝对是噩梦开始,尝试了很多东西。做了每个层次结构的表TPH的东西,这是在EF核心的继承。我不相信这可以在多个数据库上实现。这里

我们正在为当前项目使用EF.Core。该项目有三个数据库,这真是一个无法避免的麻烦。这些数据库具有相同的结构。因此,我们能够交换上下文并使用相同的EF模型来执行CRUD操作

我们将从传统的ADO.NET原始SQL移植一个特别复杂的查询。问题是它是一个跨数据库查询。要复制这个问题,我们真正需要的是一种方法,从同一dbContext中的三个数据库中获取所讨论查询的所有三个表

绝对是噩梦开始,尝试了很多东西。做了每个层次结构的表TPH的东西,这是在EF核心的继承。我不相信这可以在多个数据库上实现。这里是我们使用的一个有用的站点

所以我们想知道是否有人有任何关于这方面的信息可以通过EF实现

有趣的问题

一个上下文不能跨多个数据库

使用多个上下文将最终在内存中加载数据并对对象执行linq,这可能是不需要的,甚至是不可能的

第一种选择是在数据库中使用链接表并对其进行查询。我认为这是最简单的

我不知道您的查询有多复杂,以及建议内存场景的数据有多大,根据您在查询中所做的工作,您可能有一些特别的解决方案,例如:

您可以实现一些枚举器,这些枚举器按照高效内存处理所需的特定顺序从一个数据库加载数据,然后您可以将它们组合在一个数据库中并使用它。 如果您的查询更多地是关于大数据上的联接,那么您必须将其打断,创建具有最少列数的对象,并在此基础上实现查询,此外,您还可以在其他查询中使用此查询结果,以加载缺少的列。 有趣的问题

一个上下文不能跨多个数据库

使用多个上下文将最终在内存中加载数据并对对象执行linq,这可能是不需要的,甚至是不可能的

第一种选择是在数据库中使用链接表并对其进行查询。我认为这是最简单的

我不知道您的查询有多复杂,以及建议内存场景的数据有多大,根据您在查询中所做的工作,您可能有一些特别的解决方案,例如:

您可以实现一些枚举器,这些枚举器按照高效内存处理所需的特定顺序从一个数据库加载数据,然后您可以将它们组合在一个数据库中并使用它。 如果您的查询更多地是关于大数据上的联接,那么您必须将其打断,创建具有最少列数的对象,并在此基础上实现查询,此外,您还可以在其他查询中使用此查询结果,以加载缺少的列。
好的,我相信我们已经找到了一种方法,可以使用EF Core进行跨数据库查询,执行过程发生在数据库上,而不是在共享内存中。因此,我将以股票系统为例来说明这一点。我希望它对某人有用

首先,需要在主表上为SQLServerDB创建同义词,以便将所有关联表链接在一起

那么我们的EF模型和派生类应该如下所示

 public abstract class Stock
 {  
   public int ID{get;set;}
   public string stockName{get;set;}
 }

 [Table("dbname.scheme.Stock", Schema = "dbo")]
 public class WinterStock : Stock
 {
   public WinterStock() : base() { }
 }

 [Table("dbname.scheme.Stock", Schema = "dbo")]
 public class SummerStock : Stock
 {
  public SummerStock() : base() { }
 }
在我们的测试方法中,我们有

  var query = _context.Set<WinterStock>().Join(_context.Set<SummerStock>(), winterStock => winterStock.stockName,summerStock => summerStock.stockName, (summerStock,winterStock) => new { summerStock, winterStock });
  var result = query.ToList();

好的,我相信我们已经找到了一种方法,可以使用EF Core进行跨数据库查询,执行过程发生在数据库上,而不是在共享内存中。因此,我将以股票系统为例来说明这一点。我希望它对某人有用

首先,需要在主表上为SQLServerDB创建同义词,以便将所有关联表链接在一起

那么我们的EF模型和派生类应该如下所示

 public abstract class Stock
 {  
   public int ID{get;set;}
   public string stockName{get;set;}
 }

 [Table("dbname.scheme.Stock", Schema = "dbo")]
 public class WinterStock : Stock
 {
   public WinterStock() : base() { }
 }

 [Table("dbname.scheme.Stock", Schema = "dbo")]
 public class SummerStock : Stock
 {
  public SummerStock() : base() { }
 }
在我们的测试方法中,我们有

  var query = _context.Set<WinterStock>().Join(_context.Set<SummerStock>(), winterStock => winterStock.stockName,summerStock => summerStock.stockName, (summerStock,winterStock) => new { summerStock, winterStock });
  var result = query.ToList();

提问者p.Joe在这里回答了他自己的问题,但我实际上无法得到有效的答案。它不起作用的原因是

[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,在解析dbname时,括号会被转义

这实际上似乎是一个已知的问题,虽然尚未确定优先顺序,但仍有一个解决方案在酝酿中:

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

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 = "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;


提问者p.Joe在这里回答了他自己的问题,但我实际上无法得到有效的答案。再 因为它不起作用

[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,在解析dbname时,括号会被转义

这实际上似乎是一个已知的问题,虽然尚未确定优先顺序,但仍有一个解决方案在酝酿中:

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

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 = "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;


谢谢你的信息。我们基本上是试图避免在内存中加载。正在尝试让数据库执行此操作。感谢您提供的信息。我们基本上是试图避免在内存中加载。试图让db来做这件事。