Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EntityFramework context across multiple projects or joining between two contexts

I have a class library project containing an EF Core db context. This is part of a framework.

I want to extend this context but without making changes to the framework project. The second context would use the same database.

I created another db context in a different class library (something similar to this). This works ok, I can make queries and create migrations separately from the other context.

But for example if I have a User entity in the first context and UserBooks in the second, when I try to make a join between the two contexts it doesn't work, getting exception

System.ArgumentNullException: Value cannot be null. Parameter name: entityType

This is a known issue.

Also tried with latest NuGet package 3.0.0-preview3.19153.1 but the only difference is that the error message is better

Cannot use multiple DbContext instances within a single query execution. Ensure the query uses a single context instance

Is there any way to

a. make joins between two contexts

or

b. extend a context in a separate project without making any (or minimal) changes to the 'main' context

like image 262
SzilardD Avatar asked Jul 18 '26 03:07

SzilardD


2 Answers

Two db-contexts means two connections. You can't join through different connections.

1. Load Data into Program

You can load you data to your program and join there. Be aware, that this is dangerous on big datasets.

var customers = new Ctx1().Customers.ToList(); // ToList() loads the data into your program
var orders = new Ctx2().Orders.ToList();

// Now we're not in the db anymore. We can do a simple List-Join:
customers.Join(orders, c => c.CustomerId, o => o.CustomerId, (c, o) => new { Customer = c, Order = o });

2. Extend your existing Context

If you want to stick to one connection you could simply extend your Context. Be aware that you're in one transaction this way.

public class FrameworkContext : DbContext
{
    public DbSet<Customer> Customers { get; set; }
}

public class ExtendedContext : FrameworkContext
{
    public DbSet<Order> Orders { get; set; }
}

Now you're allowed to join:

var ctx = new ExtendedContext();

var myResult = ctx.customers.Join(ctx.orders, c => c.CustomerId, o => o.CustomerId, (c, o) => new { Customer = c, Order = o });
like image 76
kara Avatar answered Jul 19 '26 17:07

kara


You could make your second context inherit the first.

public class MyFirstContext : DbContext
{
    public DbSet<User> Users { get; set; }
}

public class MySecondContext : MyFirstContext
{
    public DbSet<UserBook> UserBooks { get; set; }
}

Of course, your second context could be in a different assembly. Now you only need MySecondContext in your application. You will be able to join Users and UserBooks.

like image 20
Knelis Avatar answered Jul 19 '26 16:07

Knelis