简体   繁体   English

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

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

In my application, for performance reasons I want to replicate the database to a separate reporting-only database, and keep my transactional work on the primary database and handle updates through synchronization on the SQL Server side.在我的应用程序中,出于性能原因,我想将数据库复制到一个单独的仅报告数据库,并将我的事务工作保留在主数据库上,并通过 SQL 服务器端的同步处理更新。 Using this, I want to offload the very intensive data-heavy database operations to the reporting-only (read-only) database.使用它,我想将非常密集的数据密集型数据库操作卸载到仅报告(只读)数据库。 The two database instances are identical in terms of schema.这两个数据库实例在架构方面是相同的。 We are developing entity framework database-first, scaffolding the database tables into our application.我们首先开发实体框架数据库,将数据库表搭建到我们的应用程序中。

I initially set this up where the reporting context used only the reporting tables, which are table schemas created to model output from the stored procedures with which all the reports are generated.我最初将其设置为报告上下文仅使用报告表,这些表是从生成所有报告的存储过程创建到 model output 的表模式。 So they were distinct names from the transactional database context and everything worked great.因此,它们是与事务数据库上下文不同的名称,并且一切都运行良好。 Now, however, we've found some other data-heavy queries that we want to offload to the reporting database as well, so we need to scaffold all of the same tables from the transactional database context to the reporting database context.然而,现在我们发现了一些其他的数据密集型查询,我们也希望将它们卸载到报告数据库中,因此我们需要将所有相同的表从事务数据库上下文搭建到报告数据库上下文中。

Here are my two scaffolding commands:这是我的两个脚手架命令:

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...

So the tables are scaffolded into a subfolder for the ReportsContext to allow the duplicate tables without overwriting the ones created by the first scaffolding command.因此,这些表被搭建到 ReportsContext 的子文件夹中,以允许重复的表格,而不会覆盖第一个搭建命令创建的表格。

When I scaffold the same tables from the two different databases into the two contexts, I get the error "'TableName' is an ambiguous reference between AppName.Model.DB.TableName and AppName.Model.DB.Reporting.TableName" for every table.当我将来自两个不同数据库的相同表搭建到两个上下文中时,我收到错误“'TableName' is an ambiguous reference between AppName.Model.DB.TableName and AppName.Model.DB.Reporting.TableName”对于每个表. The context you use properly identifies the class/table you're referencing, but the instantiation of the table class doesn't know which copy of the table it's supposed to be referencing.您使用的上下文正确地标识了您正在引用的类/表,但是表 class 的实例化不知道它应该引用的表的哪个副本。 I would really hate to have to fully-qualify every database model class throughout the application, is there an easier way that I'm missing?我真的不想在整个应用程序中对每个数据库 model class 进行完全限定,有没有我缺少的更简单的方法?

If you take your DB context, make it abstract (not vital, but stops you new'ing it accidentally) and change its constructor signature:如果您采用数据库上下文,请将其抽象化(不是很重要,但会阻止您不小心更新它)并更改其构造函数签名:

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

And then make a couple of new do-nothing contexts that extend it and pass the options through to the base constructor:然后创建几个新的不做任何事情的上下文来扩展它并将选项传递给基本构造函数:

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

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

}

And register them with different connection strings:并使用不同的连接字符串注册它们:

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

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

Then you can get the injector to inject the different context depending on what it sees you use然后你可以让注入器根据它看到你使用的内容来注入不同的上下文

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

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

There are other ways of varying the connection string, but if you're familiar with and happy with the way getting a context via DI works then it can be handy and simple to just change the connected database by varying the Type of the injected context, or injecting both if you have some heavy reporting/querying need but some updates etc to make too.还有其他改变连接字符串的方法,但是如果您熟悉并满意通过 DI 工作获取上下文的方式,那么通过改变注入上下文的类型来更改连接的数据库会很方便和简单,或者如果您有一些繁重的报告/查询需求但同时需要进行一些更新等,则同时注入两者。 You might eventually start to add some things that were specific to only one context too.. A similar approach could perhaps be taken with interfaces too, though there's a bit more typing involved in specifying which members of the context are members of the interface so that when you say UsersController(IReportingDbContext x) { x.<thing> then <thing> is actually there without a cast您可能最终也开始添加一些特定于一个上下文的东西。类似的方法也可以用于接口,尽管在指定上下文的哪些成员是接口的成员时涉及更多的类型,以便当你说UsersController(IReportingDbContext x) { x.<thing>然后<thing>实际上是没有演员

Other methods such as setting the connection string after you get the context are possible with later EFs..其他方法,例如在获取上下文后设置连接字符串,在以后的 EF 中是可能的。

when you dependency inject in your controller or class the solver will bind to the correct data context.当您在 controller 或 class 中依赖注入时,求解器将绑定到正确的数据上下文。 Ensure the connection strings are unique for each datacontext.确保连接字符串对于每个数据上下文都是唯一的。

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

相关问题 将代码优先实体框架指向创建的数据库 - Pointing a Code First Entity Framework to a created database 如何创建一个表有两个外键使用实体框架代码首先指向同一个表 - How to create a table with two foreign keys pointing to the same table using Entity Framework Code First 我可以创建两个实体框架的上下文都完全相同的模型吗? - Can I Create Two Entity Framework Contexts That Have The Exact Same Model For Both Contexts? 实体框架-表需要两个指向同一表的外键 - Entity Framework - table needs two foreign keys pointing at same table 实体框架4:代码优先 - 在另一个模式中创建数据库? MapSingleType? - Entity Framework 4: Code First - Creating db in another schema? MapSingleType? 实体框架数据库优先:在运行时模式下连接到特定的数据库架构 - Entity Framework Database First: connect to a particular database schema in runtime mode 将相同的对象附加到Entity Framework 6中的不同上下文 - Attach same object to different contexts in Entity Framework 6 两个嵌套的Entity Framework上下文,共享一个事务 - Two nested Entity Framework contexts, sharing a transaction 实体框架 6:创建具有多个上下文的数据库 - Entity Framework 6: Creating database with multiple contexts 实体框架中两个上下文之间的 Inheritance - Inheritance between two contexts in Entity Framework
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM