Zach
Zach

Reputation: 447

Pass DbContextOptions<dbContext> to base context

I need to set up a one-to-one relationship between two tables that reside in two separate databases: db1.Asset and db2.AssetExtra. This relationship does not exist in the database, so I need to set it up using the Fluent Api, which I did according to the documentation.

BaseContext.OnModelCreating(ModelBuilder modelBuilder) contains this (other things omitted for brevity):

modelBuilder.Entity<Asset>()
   .HasOne(a => a.AssetExtra)
   .WithOne(e => e.Asset)
   .HasForeignKey<AssetExtra>(e => e.AssetId);

Asset.cs has an AssetExtra property, and AssetExtra.cs has an Asset and an AssetId property:

public partial class AssetExtra
{
    public int AssetId { get; set; }

    public Asset Asset { get; set; }
}

public partial class Asset
{
    public int AssetId { get; set; }

    public int AssetExtra { get; set; }
}

In Startup.cs, each context is injected with its connection string:

services.AddDbContext<db1Context>(options => options.UseSqlServer(this.Configuration.GetConnectionString("db1")));
services.AddDbContext<db2Context>(options => options.UseSqlServer(this.Configuration.GetConnectionString("db2")));

Following the example in this answer, I'm trying to create one base context which holds all of the DbSets and sets up all of the model relationships for both databases:

public class BaseContext : DbContext
{    
    public BaseContext(DbContextOptions<db1Context> options)
        : base(options)
    {
    }

    public BaseContext(DbContextOptions<db2Context> options)
        : base(options)
    {
    }
}

public class db1Context : BaseContext
{
    public db1Context()
    {
    }

    public db1Context(DbContextOptions<db1Context> options)
        : base(options)
    {
    }
}

public class db2Context : BaseContext
{
    public db2Context()
    {
    }

    public db2Context(DbContextOptions<db2Context> options)
        : base(options)
    {
    }
}

When I try to use .Include() to include AssetExtra with Asset, I get a runtime error:

var assets = this.db1Context.Assets.Where(m => assetIds.Contains(m.AssetId))    
.Include(a => a.AssetExtra)
.ToList();

SqlException: Invalid object name Asset.AssetExtra.

Which I assume is because the AssetExtra relationship doesn't actually exist in the database? How can I get this working?

Upvotes: 0

Views: 1182

Answers (1)

Camilo Terevinto
Camilo Terevinto

Reputation: 32053

I'm afraid you cannot do this using Entity Framework. It is designed to be used one context - one database. Relationships must be configured as part of the model which means they must point to valid objects in the database you are connecting to.

What you are looking for is:

  1. Not a valid constraint, since constraints are stored in the database and can only reference items that live in the database schema. There's a reason you mention the relationship doesn't exist and you are looking to do this through code, isn't there? I would suggest you to read this Q&A: Add Foreign Key relationship between two Databases.
  2. Not an actually logical relationship even if it was stored in a single database, since one-to-one required relationships are impossible to model (think what entity inserts the ID of the other entity). This Q&A can provide more details: Entity Framework Code First One-to-One Required-Required Relationship

I think you need to take a deep look at what you are trying to achieve and how.

Upvotes: 2

Related Questions