EF Core 8中导航属性始终仅获取一条记录的问题排查
问题原因及解决方案
核心问题:未正确加载导航属性
你遇到的问题是因为查询States时,EF默认不会自动加载关联的Customers导航属性,导致result.Customers并未从数据库获取真实数据,而是使用了类初始化时的空列表(或上下文跟踪的少量数据),所以计数异常。直接查询Customers表是直接从数据库获取数据,因此结果正确。
解决方案
方案1:显式包含导航属性(推荐)
在查询States时,使用Include方法显式指定要加载关联的Customers集合,这样EF会生成联表查询,一次性加载州和对应的所有客户:
public List<Customer> Get(string stateName) { var state = _appDbContext.States .Include(s => s.Customers) // 关键:添加Include加载导航属性 .Where(s => s.Name == stateName) .FirstOrDefault(); return state?.Customers.ToList() ?? new List<Customer>(); }
方案2:启用延迟加载(可选)
如果你希望访问导航属性时自动加载数据,可以启用EF的延迟加载功能:
- 安装
Microsoft.EntityFrameworkCore.ProxiesNuGet包 - 在DbContext的配置方法中启用延迟加载:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseLazyLoadingProxies() .UseSqlServer("你的数据库连接字符串"); }
启用后,当你访问state.Customers时,EF会自动执行查询加载关联数据,但这种方式可能导致N+1查询问题(先查州,再查每个州的客户),性能不如显式Include。
额外优化建议
- 修正模型与数据库的匹配:数据库中
Customers.State_Id是可空的(NULL),但你的Customer类中State_Id是int(非可空),这会导致数据库中State_Id为NULL的记录无法被正确映射,建议改为int? State_Id:
public class Customer { // ...其他属性 public int? State_Id { get; set; } // 改为可空类型 }
- 移除冗余配置:
OnModelCreating中的modelBuilder.Entity<State>().HasMany(s => s.Customers);是冗余配置,因为你已经在Customer的配置中通过.WithMany(s => s.Customers)指定了关联关系,删除这行避免重复配置。
内容的提问来源于stack exchange,提问作者user2243747
相关产品推荐
相关产品推荐

