繁体   English   中英

一个实体类型有多个数据库上下文?

[英]One entity type multiple database contexts?

上下文继承

// MobileContext has VisitPlan, Customer, etc. that all the following contexts need.
public MobileContext : DbContext { } 
public AuthenticationEntities : MobileContext { }
public OrderEntities : MobileContext { }
public ThriftEntities : MobileContext { }

上下文是代码优先的,我不使用它们来创建数据库。

描述

我创建了一个UserPermissionService实例,该实例具有用于VisitPlanUserBranch等的存储库。所有存储库都位于AuthenticationEntities其中CustomerVisitPlanMobileContext的一部分, AuthenticationEntites和所有其他上下文都继承VisitPlan

问题

当我尝试执行将UserBranchVisitPlan连接UserBranch的查询时,它告诉我无法在两个上下文之间进行查询,但是如果在调试器中DbContext存储库的DbContext ,它们的类型均为AuthenticationEntities

有没有办法做到这一点?


查询

//
// 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
    );

哪里:

  • VisitPlans的类型为Repository<VisitPlan> ,它使用AuthenticationEntities作为其DbContext
  • Customers的类型为Repository<Customer> ,它使用AuthenticationEntities作为其DbContext
  • Branches的类型为Repository<UserBranch> ,它使用AuthenticationEntities作为其DbContext
  • Routes的类型为Repository<UserRoute> ,它使用AuthenticationEntities作为其DbContext
  • DriverNumbers的类型为Repository<UserDriverNumber> ,它使用AuthenticationEntities作为其DbContext

它们是相同类型没关系。 您必须使用DbContext的单个实例。 使用实体框架时,必须在该单个上下文实例上执行单个查询(在这种情况下为Join )。

理想情况下,您应该只使用一个负责对数据库进行所有查询的DbContext实例。 您拥有多个实例(针对单个请求)的唯一原因是,如果您正在使用多个数据库。

但是,假设您确实需要具有多个上下文对象。 您需要做的是查询每个上下文并将结果拉到内存中。 这可以通过在每个查询的末尾调用.ToList()来完成。

一旦数据存储起来,就可以将它们连接在一起。 这是一个例子:

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);

但是,根据您发布的内容,您绝对不需要多个上下文实例。 您的存储库代码很可能是不必要的,它持有或创建与其他存储库的上下文对象不同的上下文。 如果您要使用延迟加载并仅在需要时才实际生成和执行查询,则它们都应该共享一个上下文实例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM