Reputation: 2865
Context Inheritance
// MobileContext has VisitPlan, Customer, etc. that all the following contexts need.
public MobileContext : DbContext { }
public AuthenticationEntities : MobileContext { }
public OrderEntities : MobileContext { }
public ThriftEntities : MobileContext { }
The contexts are code-first and I do not use them to create the database.
Description
I create an instance of UserPermissionService
which has repositories for VisitPlan
, UserBranch
, etc. All of the repositories are in the AuthenticationEntities
with Customer
and VisitPlan
being a part of MobileContext
which AuthenticationEntites
and all other contexts inherit from.
Problem
When I try to execute a query that joins UserBranch
and VisitPlan
it tells me I cannot query between two contexts, but if I look in the debugger at the DbContext
of the repositories they are both of type AuthenticationEntities
.
Is there a way to accomplish this?
The Query
//
// USER-BRANCHES: Check the user branches table for permissions.
//
var branches = Branches
.GetAll()
.Where(x => x.AzureUser.Username == username && x.StartDate <= effective && x.EndDate >= effective);
//
// USER-ROUTES: Check the user routes table for permissions.
//
var routes = Routes
.GetAll()
.Where(x => x.AzureUser.Username == username && x.StartDate <= effective && x.EndDate >= effective);
//
// USER-DRIVERS: Check the user driver number table for permissions.
//
var drivers = DriverNumbers
.GetAll()
.Where(x => x.AzureUser.Username == username && x.StartDate <= effective && x.EndDate >= effective);
//
// VISIT PLANS: Retrieve a list of visit plans currently active.
//
var vpQuery = VisitPlans
.GetAll()
.Where(
x => x.FromDate <= effective && x.ToDate >= effective
&& (
branches.Any(b => b.Branch == x.Branch)
|| routes.Any(r => r.Route == x.Route)
|| drivers.Any(d => d.DriverNumber == x.DriverNumber)
)
);
//
// QUERY: Retrieve all the customers which have effective stop plans and are included in one of the above queries.
//
var customerQuery = vpQuery
.Join(
inner: Customers.GetAll(),
outerKeySelector: x => x.SAPCustomerID,
innerKeySelector: x => x.SAPCustomerID,
resultSelector: (vp, c) => c
);
Where:
VisitPlans
is of type Repository<VisitPlan>
which is using AuthenticationEntities
as its DbContext
Customers
is of type Repository<Customer>
which is using AuthenticationEntities
as its DbContext
Branches
is of type Repository<UserBranch>
which is using AuthenticationEntities
as its DbContext
Routes
is of type Repository<UserRoute>
which is using AuthenticationEntities
as its DbContext
DriverNumbers
is of type Repository<UserDriverNumber>
which is using AuthenticationEntities
as its DbContext
Upvotes: 0
Views: 2712
Reputation: 7097
It doesn't matter that they are of the same type. You must be using a single instance of your DbContext
. A single query (Join
in this case) must be done on that single context instance when using entity framework.
Ideally, you should only be using a single DbContext
instance that's responsible for making all of the queries to the database. The only reason you would have multiple instances (for a single request) would be if you are using multiple databases.
However, let's assume that you DO need to have multiple context objects. What you would need to do is query each context and pull the results into memory. This can be done by calling .ToList()
at the end of each query.
Once the data is memory you can join them together. Here's an example:
var vpQuery = authContext.VisitPlan.Where(x => x == something).ToList();
var ubQuery = permissionContext.UserBranch.Where(u => u == somethingElse).ToList();
var joined = vpQuery.Join(vpQuery, vp => vp.UserKey, ub => ub.UserKey, (vp, ub) => new { Property1 = ub.Something, Property2 = vp.SomethingElse);
However, based on what you posted, you definitely don't need multiple context instances. Most likely your repository code, which is probably unnecessary, is holding or creating a context that is different from the other repositories's context object(s). They should all be sharing a single context instance if you want to use lazy loading and actually generate & execute the query only when needed.
Upvotes: 2