• Entity Framework 三


    DbContext:上下文

    EDM将生成从System.Data.Entity.DbContext派生的SchoolDBEntities类,如下所示。派生DbContext的类在实体框架中被称为上下文类。

    EntityFramework 4.1之前,EDM用于生成从ObjectContext类派生的上下文类使用ObjectContext有点棘手。DbContext在概念上与ObjectContext相似

    它是ObjectContext的一个包装器,在所有的开发模型中都是有用的:Code First,Model First和Database First。

    DbContext是实体框架的重要组成部分。它是您的域或实体类与数据库之间的桥梁。

     

    DbContext是负责与数据交互作为对象的主要类。DbContext负责以下活动:

    • EntitySet: DbContext包含映射到数据库表的所有实体的实体集(DbSet <TEntity>)。
    • 查询(QueryingTo DB): DbContext将LINQ-to-Entities查询转换为SQL查询并将其发送到数据库。
    • 更改跟踪(Change Tracking):跟踪实体在从数据库查询后发生的更改。
    • 持久数据(Persistence):它还根据实体的状态对数据库执行插入,更新和删除操作
    • 缓存(Caching): DbContext默认进行一级缓存它存储在上下文类生命周期中已经被检索的实体。
    • 管理关系(Manage Relationship): DbContext还使用DB-First或Model-First方法使用CSDL,MSL和SSDL或者使用Code-First方法使用流利的API来管理关系。
    • 对象实现(Object Materialization): DbContext将原始表数据转换为实体对象。

     Context类重写OnModelCreating方法。参数DbModelBuilder被称为Fluent API,可以用Code-First方法配置实体。(我们现在可以不用研究这个)

    实例化 DbContext 

     

    从DbContext获取ObjectContext:

    对于所有常见任务,DBContext API比ObjectContext API更易于使用。但是,您可以从DBContext获取ObjectContext的引用,以便使用ObjectContext的一些功能。这可以通过使用IObjectContextAdpter来完成,如下所示:

    实体框架中的实体类型:

    EDM包含数据库中每个表的实体。实体框架5.0 / 6.0中有两种类型的实体:POCO实体动态代理实体

    POCO实体(普通的旧CLR对象):

    POCO类是不依赖任何框架特定的基类的类。它就像任何其他正常的.net类,这就是为什么它被称为“普通旧CLR对象”。

    这些POCO实体(也称为持久性无关对象)支持大部分与由实体数据模型生成的实体类型相同的查询,插入,更新和删除行为。以下是Student POCO实体的一个例子。

    动态代理(POCO代理):

    动态代理是POCO实体的运行时代理类。它就像一个POCO实体的包装类。动态代理实体允许延迟加载自动更改跟踪

    POCO实体应符合以下要求成为POCO代理人:

    1. POCO类必须声明为公共访问
    2. 一个POCO类不能被密封(在Visual Basic中不可以)
    3. POCO类不能是抽象的(Visual Basic中的MustInherit)。
    4. 每个导航属性都必须声明为公共的,虚拟的
    5. 每个集合属性必须是ICollection <T>
    6. ProxyCreationEnabled选项在上下文类中不能为false(默认为true)

    以下学生POCO实体满足上述所有要求,以便在运行时成为动态代理实体。

      

    注意:默认情况下动态代理为每个实体启用但是,您可以通过在上下文类中将ProxyCreationEnabled选项设置为false来禁用动态代理

    EDM默认生成符合上述动态代理要求的POCO实体。

     在运行时,Student的类型将是System.Data.Entity.DynamicProxies.Student,如下所示:

    从动态代理获取实际的实体类型:

    您可以使用ObjectContext.GetObjectType()来查找动态代理的实际类型,如下所示:

     

    实体可以有两种类型的属性,标量和导航属性。

    标量属性:

    标量属性是实际值包含在实体中的属性例如,Student实体具有标量属性,如StudentId和StudentName这些对应于Student表列。

    导航属性:

    导航属性是指向其他相关实体的指针学生将标准属性作为导航属性,使应用程序能够从学生导航到相关的标准实体。

     

    实体关系:

    实体框架支持三种类型的关系,与数据库一样:1)一对一2)一对多,3)多对多。

     一对一        一个学生只有一个地址

    一对多       一个老师只有一个标准

    正如您在上面的代码片段中看到的,标准实体类具有ICollection类型的Teachers属性,以便它可以包含多个Teacher对象。(它使用HashSet <Teacher>在构造函数中初始化Teachers属性,以便您可以将Teacher对象添加到集合中,而不必担心初始化。) 我们创建的时候勾选了外键所以这个类出现了 StandardId属性。

      多对多         一个学生可以报名参加很多课程,而且一门课程可以教给很多学生。

      

    注:实体框架支持许多一对多的关系,只有当接合表(StudentCourse在这种情况下)不包括除两个表中的PK之外的任何列(只有两个主键)如果连接表包含其他列(如DateCreated),则EDM也会为中间表创建实体,并且您将不得不手动管理多对多实体的CRUD操作。

    在XML视图中打开EDM。您可以看到SSDL(概念架构)具有StudentCourse实体集,但是CSDL(存储架构)没有StudentCourse实体集而是将其映射到学生和课程实体的导航属性中。在MSL(CS映射)中,它将Student和Course之间的映射放入<AssociationSetMapping />的StudentCourse表中

    因此,EDM中的CS映射正在管理多对多关系。因此,当您在课程中添加学生或在学生实体中添加课程时,当您保存它时,会将添加的学生和课程的PK插入StudentCourse表中。所以这个映射不仅可以直接在两个实体之间建立一个方便的关联,还可以管理这个关节的查询,插入和更新。

    实体生命周期:

    在实体的生命周期中,每个实体都有一个基于通过上下文(DbContext)对其执行的操作的实体状态。实体状态是System.Data.Entity.EntityState类型的枚举,包含以下值:

    1. 添加
    2. 删除
    3. 改性
    4. 不变
    5. 超脱

    上下文不仅保存了从数据库中检索到的所有对象的引用,而且保存了实体状态,并保持对实体属性的修改此功能被称为更改跟踪

    实体状态从“未更改”状态到“已修改”状态的更改是上下文自动处理的唯一状态。所有其他更改必须使用DbContext和DbSet的适当方法显式进行

    下图说明了在实体上执行的操作如何改变其状态,这又反过来影响了数据库操作。

     

    当我们只了一些增删改的操作,如果需要保存到数据库就需要调用上下文的 SavaChanges()方法。 

  • 相关阅读:
    JavaScript 基础知识 4
    JavaScript 基础知识 5 函数
    JavaScript 基础知识 3
    JavaScript 基础知识 2
    JavaScript 基础知识 1
    JavaScript 一
    HTML <a>等元素
    HTML CSS
    HTML <head> 元素
    HTML <meta> 标签
  • 原文地址:https://www.cnblogs.com/Sea1ee/p/7826112.html
Copyright © 2020-2023  润新知