.net core 2.2 自动加载相关数据
Related Data Automatically Loaded in .net core 2.2
我正在使用 .net core 2.2 和 Entity Framework Code-First,我创建了一些具有关系的模型,并且所有关系都运行良好,除非与自动加载相关数据的查找模型的关系模型和逆模型 属性 也是
代码如下:
Company.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; }
}
Address.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 个关系与相同的 table 查找”加载所有数据并自动反转,我需要知道为什么会这样我该如何阻止它。
提前致谢。
你的问题很难理解,但我相信这里的 "issue" 是 EF 的对象修正。我引用"issue",因为这实际上是一个特征。
EF 有一个对象缓存。每当您查询任何内容时,创建的实例都存储在该对象缓存中,允许从该缓存中提取相同实例的未来查询,而不必再次往返数据库。
当涉及到关系时,如果 EF 在其对象缓存中已有相关实体,它会执行 "fixup",它会自动将相关实例添加到导航 属性。同样,这是一项优化功能,因为现在您不需要发出另一个查询来检索这些内容。
解决此问题的唯一方法是在查询时使用 AsNoTracking
。例如:
var companies = await _context.Companies.AsNoTracking().ToListAsync();
对于 AsNoTracking
,EF 将不会维护对象缓存,也不会对这些实体执行更改跟踪。最后一部分很重要,因为如果您试图以任何方式修改这些实体,那么您需要 非常 小心,因为在您明确附加它们之前,EF 不会知道它们。但是,如果您只是执行读取,无论如何使用 AsNoTracking
实际上性能更高。
我正在使用 .net core 2.2 和 Entity Framework Code-First,我创建了一些具有关系的模型,并且所有关系都运行良好,除非与自动加载相关数据的查找模型的关系模型和逆模型 属性 也是
代码如下:
Company.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; }
}
Address.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 个关系与相同的 table 查找”加载所有数据并自动反转,我需要知道为什么会这样我该如何阻止它。
提前致谢。
你的问题很难理解,但我相信这里的 "issue" 是 EF 的对象修正。我引用"issue",因为这实际上是一个特征。
EF 有一个对象缓存。每当您查询任何内容时,创建的实例都存储在该对象缓存中,允许从该缓存中提取相同实例的未来查询,而不必再次往返数据库。
当涉及到关系时,如果 EF 在其对象缓存中已有相关实体,它会执行 "fixup",它会自动将相关实例添加到导航 属性。同样,这是一项优化功能,因为现在您不需要发出另一个查询来检索这些内容。
解决此问题的唯一方法是在查询时使用 AsNoTracking
。例如:
var companies = await _context.Companies.AsNoTracking().ToListAsync();
对于 AsNoTracking
,EF 将不会维护对象缓存,也不会对这些实体执行更改跟踪。最后一部分很重要,因为如果您试图以任何方式修改这些实体,那么您需要 非常 小心,因为在您明确附加它们之前,EF 不会知道它们。但是,如果您只是执行读取,无论如何使用 AsNoTracking
实际上性能更高。