ASP.NET:context.Routes与context.Set<Route>()的底层差异探究
context.Routes 和 context.Set<Route>() 的底层区别 场景代码
用户定义的DbContext类:
public class AppDbContext : DbContext { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } public DbSet<Route> Routes { get; set; } }
核心疑问
使用context.Routes和context.Set<Route>()在底层有什么区别?用户通过以下代码验证发现两者实例不相等:
Console.WriteLine(context.Routes.Equals(context.Set<Route>())) // 输出 False
底层区别解析
context.Routes的本质:这是在DbContext中显式声明的自动实现属性。默认情况下,该属性的get访问器在首次被调用时,会内部调用context.Set<Route>()完成初始化,之后每次访问都会返回这个已初始化好的实例。context.Set<Route>()的本质:每次调用该方法时,EF Core会从内部服务容器中获取或创建对应实体类型的DbSet<T>实例。
实例不相等的原因
EF Core中的DbSet<T>是基于代理/包装类实现的:
- 显式声明的
Routes属性初始化后,会持有一个固定的代理实例; - 直接调用
Set<T>()时,EF Core可能返回另一个包装了相同底层查询逻辑的代理实例,这两个实例的引用地址不同,因此默认的引用相等判断(Equals)会返回false。
但需要明确:两者的功能完全等价,最终都会关联到同一个实体集合的元数据,执行查询、新增、删除、修改等操作的底层逻辑完全一致。
补充说明
如果手动给Routes属性赋值(比如在DbContext构造函数中),context.Routes会返回自定义的实例,而Set<T>()仍会从EF内部容器获取实例,此时两者差异会更明显,但通常不建议手动赋值,让EF自动初始化即可。
内容的提问来源于stack exchange,提问作者l.diazborg
相关产品推荐
相关产品推荐

