EF Core Include() in Many to Many relation

纵饮孤独 提交于 2019-12-12 12:19:29

问题


The relation between Product and Customer is of type many-to-many (from a design point a view).

Using EF Core, we split this relation in two one-to-many relations with a third entity: 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 is a list of Records containing the quantity of data used by a certain customer while he is using a product

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

Now, if i try to read a specific UsageRecord, the ProductCustomer object is null (perfect, i am using an eager loading approach)

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

But if i specifically ask to Include() the ProductCustomer entity, the entity framwork, not only includes all the recursive references but also includes the Product object and NOT the Customer!

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

First thing: I don't understand why it is including the whole chain of objects if i specifically ask just for the ProductCustomer one.

Second thing: Why the Product and NOT the Customer?!


I include for completeness the Context model:

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

回答1:


Basically the answer is provided by the following Tip in the Loading Related Data - Eager loading section of the EF Core documentation (highlight is mine):

Entity Framework Core will automatically fix-up navigation properties to any other entities that were previously loaded into the context instance. So even if you don't explicitly include the data for a navigation property, the property may still be populated if some or all of the related entities were previously loaded.



来源:https://stackoverflow.com/questions/43374526/ef-core-include-in-many-to-many-relation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!