理解EntityFramework两个核心类型的职责 DbSet和D'bContext
DbSet与DbContext是多对一的关系
DbSet是实体对象的集合,提供了实现CRUD的相应方法
DbContext封装与数据库和数据模型相关的功能,依据数据实体状态创建SQL命令,将数据更改保存到数据库中。
下面开始详细叙述
CRUD功能的核心对象-----DbContext
DbContext三个重要属性:
1.ChangeTracker:DbChangeTracker 负责跟踪数据实体的状态
2.Configuration:DbContextConfiguration控制数据实体对象模型的行为特性和相关参数
3.Database:Database封装一些与数据库相关的功能,比如直接发送sql命令和启动事务
DbSet包容实现CRUD的相关方法
数据实体对象的状态
在程序运行时,数据实体(Data Entity)对象总处于以下状态之一
和Entity一对一关联的另一个类DbEntity<TEnitiy>中有一个属性State:EntityState就引用了数据实体状态的信息,通过获取DbEntity<TEnitiy>对象,就可以知道和它相关联的对象是处于哪种状态
EF数据更新原理
DbContext对象中包含一个ChangeTracker属性,它是一个DbChangeTracker类,
当EF从查询结果中提取数据创建实体类时,它会同步创建另一个对应的DbEntity对象,加入到DbChangeTracker对象的Entries集合中
在需要时,我们可以使用DbContext.Entity(entity)方法获取entity所对应的状态对象,从而了解对象当前所处的状态
实体对象状态的确定
Change Tracker对象通过比对CurrentValues和OriginalVlaues即可确定实体对象状态,并设置DbEntityEntry.State属性为合适的值
在合适的时机,DbContext.ChangeTracker对象检查对象属性值的更改或DbSet对象集合中对象个数的变化,负责同步更新对应的DbEntityEntry对象
SQL命令的生成
在DbContext对象调用SaveChanges()方法时,会在内部调用DbChangeTracker的DetectChanges()方法更新所有实体对象的状态值,接着就可以动态生成SQL语句
AsNoTracking()的影响
使用AsNoTracking()禁用状态跟踪之后,对应的数据实体状态为Detached 。不再允许访问CurrentValues和OriginalValues两个属性(强行访问会抛出InvalidOperationException异常)DbContext.SaveChanges()方法会因为检测不到数据变更不会生成任何的SQL命令发送给数据库