【问题标题】:Including a Model from different DbContext包括来自不同 DbContext 的模型
【发布时间】:2020-09-09 16:29:00
【问题描述】:

我不确定如何实现 2 个 DbContext 之间的关系。 PurchaseOrderDbContext 是一种代码优先的方法,而 AgencyDbContext 是一个现有的数据库。如何根据 PurchaseOrder DivisionId 包含来自 AgencyDbContext 的“部门”?

从这里开始是我的代码的一个非常简化的版本。

采购订单模型

   namespace Website.Models.PurchaseOrders
  {
    public class PurchaseOrder
    {
    public int ID { get; set; }
    public DateTime OrderDate { get; set; } 
    public string Name { get; set; }     
    public int DivisionId { get; set; }
    public int StatusID { get; set; }    
    public Agency.Division Division { get; set; }
    } 
  }

划分模型(这是在不同的 DbContext 中)

    namespace Website.Models.Agency
{
    public class Division
    {
            public int DivisionId { get; set; }
            public string DivisionName { get; set; }
            public string DivisionShortName { get; set; }
            public string DivisionAbbrev { get; set; }
            public int? DivisionDirectorEmpId { get; set; }

    }
}

Agency DbContext

    namespace Website.Models.Agency
{
    public class AgencyDbContext : DbContext
    {


        public Agency DbContext(DbContextOptions<AgencyDbContext> options) : base(options)
        {

        }

        public virtual DbSet<Division> Division { get; set; }
        public virtual DbSet<Section> Section { get; set; }


        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {

        }
    }
}

PurchaseOrderDbContext

  namespace Website.Models.PurchaseOrders
{
    public class PurchaseOrderDbContext : DbContext
    {

        public PurchaseOrderDbContext(DbContextOptions<PurchaseOrderDbContext> options) : base(options)
        {}
        public DbSet<Status> Statuses { get; set; }
        public DbSet<PurchaseOrder> PurchaseOrder { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
        }

    }

    }

我收到错误 InvalidOperationException:在 Include 中使用的 Lambda 表达式无效。这是指 Division 上的 Include 扩展。

                 var purchaseOrder = _context.PurchaseOrder
                                    .Include(p => p.Division)
                                    .Include(p => p.Status)
                                    .OrderByDescending(p => p.OrderDate);

提前谢谢你!

【问题讨论】:

  • 上下文是否针对同一个数据库?那么您需要将除法包含在purchaseorderdbcontext 中,以使包含成为可能。如果没有,那么您需要进行 2 次查询,首先是针对采购订单,然后通过代理 db 通过您从第一个查询中获得的部门 id 获取链接的部门
  • 只使用了两个数据库,PurchaseOrder 和 Agency。那么我会添加一个 Virtual Dbset 到 PurchaseOrderDbContext 吗?
  • 如果采购订单数据库中不存在分区表,则无济于事。 EF 只能用于在单个数据库中进行查询。
  • 如果数据库在单个服务器上并且它支持视图或同义词(如 SQL 服务器或 Azure SQL 数据库托管实例,那么你可以)有一个 DbContext 通过将一些实体映射到使用两个数据库中的表意见/同义词。您必须阻止迁移管理映射到视图或同义词的实体的表。

标签: entity-framework asp.net-core model-view-controller


【解决方案1】:

解决问题的唯一方法可能是在第一个上下文中查询您要查找的项目,然后使用来自第二个上下文的条目填充 Division 属性

public class PurchaseOrderService
{
    private readonly PurchaseOrderDbContext purchaseOrderDbContext;
    private readonly AgencyDbContext agencyDbContext;

    public PurchaseOrderService(PurchaseOrderDbContext purchaseOrderDbContext,
        AgencyDbContext agencyDbContext)
    {
        this.purchaseOrderDbContext = purchaseOrderDbContext;
        this.agencyDbContext = agencyDbContext;
    }

    public PurchaseOrder Get(int id)
    {
        var purchaseOrder = purchaseOrderDbContext.PurchaseOrder.FirstOrDefault(x => x.ID == id);

        if (purchaseOrder == null)
        {
            return null;
        }

        purchaseOrder.Division = agencyDbContext.Division.FirstOrDefault(x => x.DivisionId == purchaseOrder.DivisionId);

        return purchaseOrder;
    }
}

【讨论】:

  • 如果我收到多个采购订单怎么办? FirstorDefault 不起作用。
  • 添加一个 foreach 并以这种方式分配部门可能会起作用。这将如何影响性能?
  • 由于糟糕的数据库设计,任何决策都会比原生决策慢。对于多个项目,您可以应用 .Where(x => divisionIds.Contains(x.DivisionId)).ToList() ,其中 divisionIds 是整数数组。
猜你喜欢
  • 2018-04-14
  • 2010-12-01
  • 2014-05-05
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
  • 2018-03-08
  • 2012-01-27
相关资源
最近更新 更多