I want to isolate the "account" tables from "data" tables for reusing on another application.
I trying to use .NET Core 2.0 + Angular template, creating 2 connection strings, but when a create the another AbpDbContext, I couldn't set the connection strings for the context.
The example of using multiples DB contexts on their GitHub uses .NET framework, not .NET core, which is permitted to set the connection string on dbcontext ctor.
How can I do this on .net core 2 template?
We specify the Initial Catalog during the connection, to define where we want to run the query, but if the user have enough permissions to execute the query on other databases, he can do that using the two dots Db.. table notation! This code will work using one connection string!
Connect with multiple database in ASP.NET ZERO/ASP.NET BOILERPLATE.
Note - Use seperate DB Context to use multiple Databases.
Step 1. Create modal class in "MultipleDbContextEfCoreDemo.Core" Project for your tables.
[Table ("tblStudent")] //Is in First Database
public class Student : Entity<long> {
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
protected Student () { }
}
[Table ("tblCourses")] //Is in Second Database
public class Courses : Entity<long> {
public int ID { get; set; }
public string CourseName { get; set; }
public string Standard { get; set; }
protected Courses () { }
}
Step 2. In same project("MultipleDbContextEfCoreDemo.Core" Project) create/use "MultipleDbContextEfCoreDemoConsts.cs" file to add Database Connection names.
public class MultipleDbContextEfCoreDemoConsts
{
public const string LocalizationSourceName = "MultipleDbContextEfCoreDemo";
public const string ConnectionStringName = "Default";
public const string SecondDbConnectionStringName = "Second";
}
Step 3. In "MultipleDbContextEfCoreDemo.EntityFrameworkCore" Project goto "EntityFrameworkCore" Folder and create individual "DBContext" and "DbContextConfigurer" file for each database connection to which you want to connect.
FirstDatabase Setting -
required files to connect to first db -
1. FirstDbContext.cs
public class FirstDbContext : AbpDbContext, IAbpPersistedGrantDbContext {
/* Define an IDbSet for each entity of the application */
public DbSet<PersistedGrantEntity> PersistedGrants { get; set; }
public virtual DbSet<Student> Student { get; set; }
public FirstDbContext (DbContextOptions<FirstDbContext> options) : base (options) {
}
protected override void OnModelCreating (ModelBuilder modelBuilder) { }
}
2. FirstDbContextConfigurer
public static class FirstDbContextConfigurer {
public static void Configure (DbContextOptionsBuilder<FirstDbContext> builder, string connectionString) {
builder.UseSqlServer (connectionString);
}
public static void Configure (DbContextOptionsBuilder<FirstDbContext> builder, DbConnection connection) {
builder.UseSqlServer (connection);
}
}
SecondDatabase Setting -
required files to connect to second db -
1. SecondDbContext.cs
public class SecondDbContext : AbpDbContext, IAbpPersistedGrantDbContext {
/* Define an IDbSet for each entity of the application */
public DbSet<PersistedGrantEntity> PersistedGrants { get; set; }
public virtual DbSet<Student> Student { get; set; }
public SecondDbContext (DbContextOptions<SecondDbContext> options) : base (options) {
}
protected override void OnModelCreating (ModelBuilder modelBuilder) { }
}
2. SecondDbContextConfigurer
public static class SecondDbContextConfigurer {
public static void Configure (DbContextOptionsBuilder<SecondDbContext> builder, string connectionString) {
builder.UseSqlServer (connectionString);
}
public static void Configure (DbContextOptionsBuilder<SecondDbContext> builder, DbConnection connection) {
builder.UseSqlServer (connection);
}
}
Step 4. Then in same project("MultipleDbContextEfCoreDemo.EntityFrameworkCore") add "MyConnectionStringResolver.cs"
public class MyConnectionStringResolver : DefaultConnectionStringResolver
{
public MyConnectionStringResolver(IAbpStartupConfiguration configuration)
: base(configuration)
{
}
public override string GetNameOrConnectionString(ConnectionStringResolveArgs args)
{
if (args["DbContextConcreteType"] as Type == typeof(SecondDbContext))
{
var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());
return configuration.GetConnectionString(MultipleDbContextEfCoreDemoConsts.SecondDbConnectionStringName);
}
return base.GetNameOrConnectionString(args);
}
}
Step 5. Then in same project("MultipleDbContextEfCoreDemo.EntityFrameworkCore"), Update "MultipleDbContextEfCoreDemoEntityFrameworkCoreModule.cs" file to replace the "IConnectionStringResolver" with our custom implementation MyConnectionStringResolver.
[DependsOn(typeof(MultipleDbContextEfCoreDemoCoreModule), typeof(AbpEntityFrameworkCoreModule))]
public class MultipleDbContextEfCoreDemoEntityFrameworkCoreModule : AbpModule
{
public override void PreInitialize()
{
Configuration.ReplaceService<IConnectionStringResolver, MyConnectionStringResolver>();
// Configure first DbContext
Configuration.Modules.AbpEfCore().AddDbContext<FirstDbContext>(options =>
{
if (options.ExistingConnection != null)
{
FirstDbContextConfigurer.Configure(options.DbContextOptions, options.ExistingConnection);
}
else
{
FirstDbContextConfigurer.Configure(options.DbContextOptions, options.ConnectionString);
}
});
// Configure second DbContext
Configuration.Modules.AbpEfCore().AddDbContext<SecondDbContext>(options =>
{
if (options.ExistingConnection != null)
{
SecondDbContextConfigurer.Configure(options.DbContextOptions, options.ExistingConnection);
}
else
{
SecondDbContextConfigurer.Configure(options.DbContextOptions, options.ConnectionString);
}
});
}
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(typeof(MultipleDbContextEfCoreDemoEntityFrameworkCoreModule).GetAssembly());
}
}
Step 6. Create the Service in "MultipleDbContextEfCoreDemo.Application" project with Dto, Interface and Service Class.
ITestAppService.cs-
public interface ITestAppService : IApplicationService
{
List<string> GetStudentAndCourses();
}
TestAppService.cs
public class TestAppService : MultipleDbContextEfCoreDemoAppServiceBase, ITestAppService
{
private readonly IRepository<Student> _studentRepository; //in the first db
private readonly IRepository<Courses> _coursesRepository; //in the second db
public TestAppService(
IRepository<Student> studentRepository,
IRepository<Courses> coursesRepository
)
{
_studentRepository = studentRepository;
_coursesRepository = coursesRepository;
}
//a sample method uses both databases concurrently
public List<string> GetStudentAndCourses()
{
List<string> names = new List<string>();
var studentNames = _studentRepository.GetAllList().Select(p => "Student: " + p.FirstName).ToList();
names.AddRange(peopleNames);
var courseNames = _coursesRepository.GetAllList().Select(p => "Course: " + p.CourseName).ToList();
names.AddRange(courseNames);
return names;
}
}
Step 7. Add Database connectionStrings to your MultipleDbContextEfCoreDemo.Web/MultipleDbContextEfCoreDemo.Web.Host project's "appsettings.json" file.
{
"ConnectionStrings": {
"Default":
"Server=XXX.XXX.XX.XX;Database=firstDB;Integrated Security=False;TrustServerCertificate=True;User ID=XX;Password=XXX;",
"Second":
"Server=XXX.XXX.XX.XX;Database=secondDB;Integrated Security=False;TrustServerCertificate=True;User ID=XX;Password=XXX;"
}
}
Step 8. Use Service in your angular/MVC project.
I ran into the same problem as @Sniipe with regards to navigational properties.
The problem was that I was inheriting from
AbpZeroDbContext<Tenant, Role, User, PortalDbContext>
in my second DBContext instead of just
AbpDbContext
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With