Same DbContext, Several databases using EF Core

一曲冷凌霜 提交于 2020-08-06 05:54:57

问题


In my App, I have some data which are stored on different databases (e.g. identity and User Info are stored separately to Content-related stuff for historical reasons).

However I would like to be able to get advantage of the '.Include' method of EF Core, but as the data is stored in a different DB, is there a way to query two databases in the same DbContext?


回答1:


One option I am seeing is to use views to get all the information from the 2nd database back to the local database.

If using SQL Server as a local database:

1. Create the database link Create linked servers or sp_addlinkedserver

(This step can be skipped if the database is on the same instance)

SQL Server Syntax:

    sp_addlinkedserver [ @server= ] 'server' [ , [ @srvproduct= ] 'product_name' ]   
       [ , [ @provider= ] 'provider_name' ] [ , [ @datasrc= ] 'data_source' ]   
       [ , [ @location= ] 'location' ] [ , [ @provstr= ] 'provider_string' ]   
       [ , [ @catalog= ] 'catalog' ]   

Example:

EXEC sp_addlinkedserver     
   @server=N'RemoteServer',   
   @srvproduct=N'',  
   @provider=N'SQLNCLI',   -- SQL Server Native Client
   @datasrc=N'RemoteIp\instance1';  

Azure Example:

------ Configure the linked server
-- Add one Windows Azure SQL DB as Linked Server
EXEC sp_addlinkedserver
  @server='RemoteServer', -- here you can specify the name of the linked server
  @srvproduct='',       
  @provider='sqlncli', -- using SQL Server Native Client
  @datasrc = 'myServer.database.windows.net',   -- add here your server name
  @location = '',
  @provstr = '',
  @catalog = 'myDatabase'-- add here your database name as initial catalog(you cannot connect to the master database)

-- Add credentials and options to this linked server
EXEC sp_addlinkedsrvlogin
    @rmtsrvname = 'RemoteServer',
    @useself = 'false',
    @rmtuser = 'myLogin',             -- add here your login on Azure DB
    @rmtpassword = 'myPassword'-- add here your password on Azure DB
EXEC sp_serveroption 'RemoteServer', 'rpc out', true;  

You can even link to data from Excel files

2. Create a view in the local DB

CREATE VIEW UserObjects AS SELECT Id, UserId, Name, Description FROM RemoteServer.myDatabase.dbo.UserObjects

3. Reference UserObjects as a normal table in the DbContext (views support INSERT/UPDATE/DELETE as long as it is built from a single source table See MS Doc)

public DbSet<User> Users {get;set;}
public DbSet<UserObject> UserObjects {get;set;}

and then use the remote table as a local one:

var user  = await _DbContext.Users.Where(u => u.FirstName = "bob").Include(u => u.Objects);

[Warning note] There is no way to have a Primary Key on a view, and therefore to link it as a foreign key constraint. It does not seem possible to add an index to a view either, which could have more or less the same performances gain, but not the constraint part... Reason:

The view must reference only base tables that are in the same database as the view

:( Therefore the following will not work, even if you create the view with the required WITH SCHEMABINDING :

CREATE UNIQUE INDEX IDX_UserObjects_PK
    ON UserObjects (Id);  
CREATE INDEX IDX_UserObjects_UserId  
    ON UserObjects (UserId);  



回答2:


If the end goal is to get records from multiple DBs, an alternative way is to call the stored procedure and use DBs in the SP.

Sample to call SP:

_databaseContext.Database.ExecuteSqlCommandAsync($"EXEC {storedProcedureName} @param1, @param2", new SqlParameter("param1", param1), new SqlParameter("param2", param2));


来源:https://stackoverflow.com/questions/49792175/same-dbcontext-several-databases-using-ef-core

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!