[Entity Framework] 学习笔记
History
在EF最初的版本中,作为一个ORM组件其通过EDM(Entity Data Model)文件(里面是一些xml)来配置数据库与实体类之间的映射,实现数据进出数据库的控制。
最初的版本中只支持Database First,即由已有数据库结构生成EDM,继而得到实体类。
后来EF在4.0版本起开始支持Model First即先建立EDM,然后生成数据库。
在4.1版本开始,EF迎来了最大的变化--开始支持Code First模式,值得注意的是Code First不是和Database First或Model First平级的概念,而是和EDM平级的概念。
使用Code First不再需要EDM来维护实体与数据库之间的映射关系,这个映射完全通过代码来完成,并在程序开始运行时在内存中建立一个映射模型,这也就是Code First这个名称中Code的含义。
由于Code First的魅力极大,EDM文件又存在不利于版本管理等天生缺陷,基本上处于一个被抛弃的状态。在EF7版本可能取消EDM的支持,只保留Code First。
使用Code First一般都是先建立实体然后通过代码配置实体到数据库的映射,继而生成数据库(如果数据库已存在,就不需要再生成数据库,可以直接建立代码映射模型),这也就是所谓的Model First模式。当然Code First也支持Database First,通过工具由现有数据库生成实体,及实体映射数据库的代码。
Core
随着Code First一起出现的DbContext和DbSet类绝对可以称得上EF的功能核心,其取代了之前的ObjectContext和ObjectSet类,提供了与数据库通信,管理内存中实体的重要功能。
DbContext类
主要是负责与数据库进行通信,管理实体到数据库的映射模型,跟踪实体的更改(正如 这个类名字Context所示,其维护了一个EF内存中容器,保存所有被加载的实体并跟踪其状态)。Dbcontext中最常用的几个方法如:
- SaveChanges(6.0开始增加的异步方法SaveChangesAsync):用于将实体的修改保存到数据库。
- Set<T>:获取实体相应的DbSet对象,我们对实体的增删改查操作都是通过这个对象来进行的。
还有几个次常用但很重要的属性方法:
- Database属性:一个数据库对象的表示,通过其SqlQuery、ExecuteSqlCommand等方法可以直接执行一些Sql语句或SqlCommand;EF6起可以通过Database对象控制事务。
- Entry:获取EF Context中的实体的状态,在更改跟踪一节会讨论其作用。
- ChangeTracker:返回一个DbChangeTracker对象,通过这个对象的Entries属性,我们可以查询EF Context中所有缓存的实体的状态。
DbSet类
这个类的对象正是通过刚刚提到的Set<T>方法获取的对象。其中的方法都与操作实体有关,如:
- Find/FindAsync:按主键获取一个实体,首先在EF Context中查找是否有被缓存过的实体,如果查找不到再去数据库查找,如果数据库中存在则缓存到EF Context并返回,否则返回null。
- Attach:将一个已存在于数据库中的对象添加到EF Context中,实体状态被标记为Unchanged。对于已有相同key的对象存在于EF Context的情况,如果这个已存在对象状态为Unchanged则不进行任何操作,否则将其状态更改为Unchanged。
- Add:将一个已存在于数据库中的对象添加到EF Context中,实体状态被标记为Added。对于已有相同key的对象存在于EF Context且状态为Added则不进行任何操作。
- Remove:将一个已存在于EF Context中的对象标记为Deleted,当SaveChanges时,这个对象对应的数据库条目被删除。注意,调用此方法需要对象已经存在于EF Context。
- Include:详见下面预加载一节。
- AsNoTracking:相见变更跟踪一节。
- Local属性:用来跟踪所有EF Context中状态为Added,Modified、Unchanged的实体。作用好像不是太大。没怎么用过。
- Create:这个方法至今好像没有用到过,不知道干啥的。有了解的评论中给解释下吧。
DBContext类, DbSet,
该派生类具有一个或多个DBSet<T>类的属性,类型DBSet<T>中的每一个T代表了一个想要持久保存的对象。
public class MusicStoreDB : DBContext { public DbSet<Album> Albums {get; set;} public DbSet<Blog> Blogs {get; set;} }