【问题标题】:EF Core Include() in Many to Many relationEF Core Include() 在多对多关系中
【发布时间】:2017-09-08 12:41:30
【问题描述】:

ProductCustomer 之间的关系是多对多类型的(从设计的角度来看)。

使用 EF Core,我们将此关系拆分为两个与第三个实体的一对多关系:ProductCustomer

public partial class ProductCustomer
{
    public long ProductId { get; set; }
    public long CustomerId { get; set; }   
    public virtual Customer Customer { get; set; }
    public virtual Product Product { get; set; }

    public virtual ICollection<UsageRecord> UsageRecord { get; set; }
}

UsageRecord 是一个记录列表,其中包含某个客户在使用产品时使用的数据量

public partial class UsageRecord
{
     public long Id { get; set; }
     public long ProductId { get; set; }
     public long CustomerId { get; set; }           
     public decimal Quantity { get; set; }                
     public virtual ProductCustomer ProductCustomer { get; set; }                
}

现在,如果我尝试读取特定的 UsageRecordProductCustomer 对象为 null(完美,我使用的是急切加载方法)

return _usageRecordEntity.Where(x => x.ProductId == productId).AsEnumerable();

但是,如果我特别要求 Include() ProductCustomer 实体,实体框架不仅包括所有递归引用,还包括 Product 对象而不是客户

return _usageRecordEntity.Where(x => x.ProductId == productId).Include(p => p.ProductCustomer).AsEnumerable();

第一件事:我不明白为什么它包括整个对象链 如果我专门要求 ProductCustomer 一个。

第二件事:为什么是产品而不是客户?!


为了完整起见,我将上下文模型包括在内:

 protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Customer>(entity =>
        {
            entity.Property(e => e.customerId)
                .IsRequired()
                .HasColumnName("CustomerId")
                .HasMaxLength(255);
        });

        modelBuilder.Entity<Product>(entity =>
        {
            entity.Property(e => e.Name)
                .IsRequired()
                .HasMaxLength(50);
        });

        modelBuilder.Entity<ProductCustomer>(entity =>
        {
            entity.HasKey(e => new { e.ProductId, e.CustomerId })
                .HasName("PK__ProductCustomerComposite");

            entity.HasOne(d => d.Customer)
                .WithMany(p => p.ProductCustomer)
                .HasForeignKey(d => d.CustomerId)
                .OnDelete(DeleteBehavior.Restrict)
                .HasConstraintName("FK__ProductCu__CustomerId");

            entity.HasOne(d => d.Product)
                .WithMany(p => p.ProductCustomer)
                .HasForeignKey(d => d.ProductId)
                .OnDelete(DeleteBehavior.Restrict)
                .HasConstraintName("FK__ProductCu__ProductId");
        });

        modelBuilder.Entity<UsageRecord>(entity =>
        {
            entity.Property(e => e.Quantity)
                .HasColumnType("decimal")
                .HasDefaultValueSql("0");

            entity.HasOne(d => d.ProductCustomer)
                .WithMany(p => p.UsageRecord)
                .HasForeignKey(d => new { d.ProductId, d.CustomerId })
                .OnDelete(DeleteBehavior.Restrict)
                .HasConstraintName("FK_UsageRecordProductcustomer");
        });
    }

【问题讨论】:

  • EF Core 中还没有多对多关系。我想你的意思是,两个一对多的关系。
  • 当然可以。产品 - 从设计的角度来看,客户是多对多的关系。但它被建模为与第三个实体“ProductCustomer”的一对多关系

标签: c# entity-framework ef-code-first lazy-loading entity-framework-core


【解决方案1】:

基本上答案是由EF Coredocumentation加载相关数据-急切加载部分中的以下提示提供的(重点是我的):

Entity Framework Core 将自动修复先前加载到上下文实例中的任何其他实体的导航属性。 因此,即使您没有明确包含导航属性的数据,如果之前加载了部分或所有相关实体,该属性仍可能会被填充

【讨论】:

    猜你喜欢
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 2018-06-02
    • 2019-01-19
    • 2017-10-26
    • 2018-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多