【问题标题】:Related Data Automatically Loaded in .net core 2.2.net core 2.2 中自动加载的相关数据
【发布时间】:2023-03-13 23:11:01
【问题描述】:

我将 .net core 2.2 与 Entity Framework Code-First 一起使用,我创建了一些具有关系的模型,并且所有关系都运行良好,除非与查找模型的关系会自动加载模型的相关数据和反向属性太

代码如下:

公司.cs

public class Company
{

    public Company()
    {
        Lookups = new HashSet<Lookup>();
    }
    
    public Guid Id { get; set; }
    
    // Relationships

    // Address
    [ForeignKey("AddressForeignKey")]
    public Address Address { get; set; }

    // User
    [InverseProperty("Company")]
    public List<User> UsersInCompany { get; set; }

    // Lookup as a country
    public Guid? CountryId { get; set; }
    public Lookup Country { get; set; }

    // Lookup as a bank
    public Guid? BankId { get; set; }
    public Lookup DefaultBank { get; set; }

    // Lookup as a socialInsuranceOffice
    public Guid? SocialInsuranceOfficeId { get; set; }
    public Lookup DefaultSocialInsuranceOffice { get; set; }

    // Lookup as a currency
    //[ForeignKey("DefaultCurrencyForeignKey")]
    public Guid? CurrencyId { get; set; }
    public Lookup Currency { get; set; }
    
    // Lookup for all lookups types
    public ICollection<Lookup> Lookups { get; set; }
    
}

地址.cs

public class Address
{
    public Guid Id { get; set; }
    
    // Relationships

    // Company
    [InverseProperty("Address")]
    public List<Company> Companies { get; set; }

    // Lookup as a governorate
    [ForeignKey("LookupForeignKey")]
    public Lookup GovernorateLookup { get; set; }
}

DataContext.Cs

   // Company and Address
        modelBuilder.Entity<Company>()
            .HasOne(u => u.Address)
            .WithMany(r => r.Companies)
            .OnDelete(DeleteBehavior.SetNull);

   // Address and Lookup
        modelBuilder.Entity<Address>()
            .HasOne(a => a.GovernorateLookup)
            .WithMany(l => l.GovernoratesUserAsAddress)
            .OnDelete(DeleteBehavior.SetNull);

  modelBuilder.Entity<Company>(com =>
        {
            // Company and Lookup for defaultCountry
            com.HasOne(c => c.Country)
            .WithMany(d => d.CompanyCountries)
            .HasForeignKey(f => f.CountryId)
            .HasConstraintName("COM_COUNTRY_FK")
            .OnDelete(DeleteBehavior.Restrict);

            // Company and Lookup for defaultBank
            com.HasOne(c => c.DefaultBank)
            .WithMany(d => d.CompanyBanks)
            .HasForeignKey(f => f.BankId)
            .HasConstraintName("COM_BANK_FK")
            .OnDelete(DeleteBehavior.Restrict);

            // Company and Lookup for defaultSocialInsuranceOffice
            com.HasOne(c => c.DefaultSocialInsuranceOffice)
            .WithMany(d => d.CompanySocialInsuranceOffices)
            .HasForeignKey(f => f.SocialInsuranceOfficeId)
            .HasConstraintName("COM_SOCIALINSURANCEOFFICE_FK")
            .OnDelete(DeleteBehavior.Restrict);

            // Company and Lookup for currency
            com.HasOne(c => c.Currency)
            .WithMany(d => d.CompanyCurrencies)
            .HasForeignKey(f => f.CurrencyId)
            .HasConstraintName("COM_CURRENCY_FK")
            .OnDelete(DeleteBehavior.Restrict);


            // Company and Lookup for all Lookups types
            com.HasMany(c => c.Lookups)
           .WithOne(d => d.Company)
           .HasForeignKey(f => f.CompanyId)
           .HasConstraintName("COM_ALL_LOOKUPS_FK")
           .OnDelete(DeleteBehavior.Cascade);

        });

请注意,所有关系都运行良好,但只有查找“我有 5 个具有同一个表查找的关系”的关系会自动加载所有数据并反向,我需要知道为什么会发生这种情况以及如何阻止它.

提前致谢。

【问题讨论】:

    标签: .net-core asp.net-core-mvc entity-framework-core asp.net-core-webapi code-first


    【解决方案1】:

    您的问题很难理解,但我相信这里的“问题”是 EF 的对象修复。我引用“问题”,因为这实际上是一个功能

    EF 有一个对象缓存。每当您查询任何内容时,创建的实例都会存储在该对象缓存中,从而允许将来从该缓存中提取相同实例的查询,而不必再次往返数据库。

    当涉及到关系时,如果 EF 在其对象缓存中已有相关实体,它会执行“修复”,将相关实例自动添加到导航属性中。同样,这是一项优化功能,因为现在您不需要发出另一个查询来检索这些。

    解决此问题的唯一方法是在查询时使用AsNoTracking。例如:

    var companies = await _context.Companies.AsNoTracking().ToListAsync();
    

    使用AsNoTracking,EF 不会维护对象缓存,也不会对这些实体执行更改跟踪。最后一部分很重要,因为如果您尝试以任何方式修改这些实体,则需要非常小心,因为在您明确附加它们之前,EF 不会意识到它们。但是,如果您只是执行读取操作,则使用 AsNoTracking 实际上性能更高。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-16
      • 2020-06-15
      • 2020-04-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多