繁体   English   中英

Entity Framework DB 前两个上下文指向同一个数据库模式

[英]Entity Framework DB First two contexts pointing to the same database schema

在我的应用程序中,出于性能原因,我想将数据库复制到一个单独的仅报告数据库,并将我的事务工作保留在主数据库上,并通过 SQL 服务器端的同步处理更新。 使用它,我想将非常密集的数据密集型数据库操作卸载到仅报告(只读)数据库。 这两个数据库实例在架构方面是相同的。 我们首先开发实体框架数据库,将数据库表搭建到我们的应用程序中。

我最初将其设置为报告上下文仅使用报告表,这些表是从生成所有报告的存储过程创建到 model output 的表模式。 因此,它们是与事务数据库上下文不同的名称,并且一切都运行良好。 然而,现在我们发现了一些其他的数据密集型查询,我们也希望将它们卸载到报告数据库中,因此我们需要将所有相同的表从事务数据库上下文搭建到报告数据库上下文中。

这是我的两个脚手架命令:

Scaffold-DbContext "Server=SERVERNAME;Database=DBNAME;User ID=ID;Password=PW;" Microsoft.EntityFrameworkCore.SqlServer -NoOnConfiguring -OutputDir Model\DB -Context TransContext -UseDatabaseNames -f -t tablenames...

Scaffold-DbContext "Server=SERVERNAME;Database=DBNAME;User ID=ID;Password=PW;" Microsoft.EntityFrameworkCore.SqlServer -NoOnConfiguring -OutputDir Model\DB\Reporting -Context ReportsContext -UseDatabaseNames -f -t tablenames...

因此,这些表被搭建到 ReportsContext 的子文件夹中,以允许重复的表格,而不会覆盖第一个搭建命令创建的表格。

当我将来自两个不同数据库的相同表搭建到两个上下文中时,我收到错误“'TableName' is an ambiguous reference between AppName.Model.DB.TableName and AppName.Model.DB.Reporting.TableName”对于每个表. 您使用的上下文正确地标识了您正在引用的类/表,但是表 class 的实例化不知道它应该引用的表的哪个副本。 我真的不想在整个应用程序中对每个数据库 model class 进行完全限定,有没有我缺少的更简单的方法?

如果您采用数据库上下文,请将其抽象化(不是很重要,但会阻止您不小心更新它)并更改其构造函数签名:

public abstract partial class MyContext: DbContext
{
    public MyContext(DbContextOptions options): base(options) {}

然后创建几个新的不做任何事情的上下文来扩展它并将选项传递给基本构造函数:

public class ReportingMyContext: MyContext 
{
    public ReportingMyContext(DbContextOptions<ReportingMyContext> options) : base(options) { }
}

public class MainMyContext: MyContext
{
    public MainMyContext(DbContextOptions<MainMyContext> options) : base(options) { }

}

并使用不同的连接字符串注册它们:

services.AddDbContext<ReportingMyContext>(options =>
    options.UseSqlServer("Data Source=blah blah blah")
);

services.AddDbContext<MainMyContext>(options =>
    options.UseSqlServer("Data Source=blow blow blow")
);

然后你可以让注入器根据它看到你使用的内容来注入不同的上下文

class ReportsController{
  ReportsController(ReportingMyContext x){
    x.SomeTable.Count() //counts reports db
  }

class UsersController{
  UsersController(MainMyContext x){
    x.SomeTable.Count() //counts main db
  }

还有其他改变连接字符串的方法,但是如果您熟悉并满意通过 DI 工作获取上下文的方式,那么通过改变注入上下文的类型来更改连接的数据库会很方便和简单,或者如果您有一些繁重的报告/查询需求但同时需要进行一些更新等,则同时注入两者。 您可能最终也开始添加一些特定于一个上下文的东西。类似的方法也可以用于接口,尽管在指定上下文的哪些成员是接口的成员时涉及更多的类型,以便当你说UsersController(IReportingDbContext x) { x.<thing>然后<thing>实际上是没有演员

其他方法,例如在获取上下文后设置连接字符串,在以后的 EF 中是可能的。

当您在 controller 或 class 中依赖注入时,求解器将绑定到正确的数据上下文。 确保连接字符串对于每个数据上下文都是唯一的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM