EF 基础(第六章: 实体 Entity)

在 Entity Framework 中什么是实体 Entity

在 EF 中一个实体就是程序域中的一个类,它在继承的上下文类中包含在 DbSet<TEntity>中作为类型属性。EF API 把每一个实体映射到一张表,把实体的每一个属性映射到数据库中的列。

例如,在 school 程序中下面的StudentStudentAddressGrade是域类。

public class Student
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public DateTime? DateOfBirth { get; set; }
    public byte[]  Photo { get; set; }
    public decimal Height { get; set; }
    public float Weight { get; set; }

    public StudentAddress StudentAddress { get; set; }
    public Grade Grade { get; set; }
}

public partial class StudentAddress
{
    public int StudentID { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }

    public Student Student { get; set; }
}

public class Grade
{
    public int GradeId { get; set; }
    public string GradeName { get; set; }
    public string Section { get; set; }

    public ICollection<Student> Students { get; set; }
}

上面的这些类当它们在上下文类(继承自DbContext)中被包含在DbSet<TEntity>中作为属性时,它们就变成了实体,如下所示。

public class SchoolContext : DbContext
{
    public SchoolContext()
    {

    }

    public DbSet<Student> Students { get; set; }
    public DbSet<StudentAddress> StudentAddresses { get; set; }
    public DbSet<Grade> Grades { get; set; }
}

在上面的上下文类中,StudentsStudentAddresses, 和 Grades 属性的类型 DbSet<TEntity> 被称为实体集。Student,,StudentAddress,,和Grade 是实体 (也叫实体类型)。

一个实体(Entity)可以包含两种类型的属性:标量属性(Scalar Properties)和导航属性(Navigation Properties)。

标量属性(Scalar Properties):

基本类型的属性称为标量属性。一个标量属性可以存储实际的数据。一个标量属性可以映射到数据库表的一个列。

导航属性(Navigation Properties):

导航属性代表和另一个实体之间的关系。
有两种类型的导航属性:引用导航(Reference Navigation)和集合导航(Collection Navigation)

引用导航属性(Reference Navigation Property):

如果一个实体中包含一个实体类型的属性,这个属性就叫引用导航属性。它代表多个中的一个。

集合导航属性(Collection Navigation Property):

如果一个实体包含一个集合类型的属性,这个属性就叫集合导航属性。它代表多个中的多个。

下面的图表解释了实体的属性:
这里写图片描述

实体的类型

Entity Framework 中的实体类型:

在Entity Framework 中有两种实体类型:简单对象实体(POCO Entities)和动态代理实体(Dynamic Proxy Entities)。

简单对象实体(Pain Old CLR Object):

一个简单对象实体是一个类,它不依赖于特定框架的中基类。它和任何 .NET CLR 中的类一样,这就是它被称为简单对象实体的原因。

简单对象实体在 EF 6 和 EF Core 中都被支持。

Entity Data Model 中生成的实体类型的查询,插入,更新和删除中的大多数行为,在简单对象实体(也叫持久无关对象)中是一模一样的。下面是一个 Student 简单对象实体的一个例子。

public class Student
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public DateTime? DateOfBirth { get; set; }
    public byte[]  Photo { get; set; }
    public decimal Height { get; set; }
    public float Weight { get; set; }

    public StudentAddress StudentAddress { get; set; }
    public Grade Grade { get; set; }
}
动态代理实体(Dynamic Proxy Entities):

动态代理是一个封装了简单对象实体的运行时代理类。动态代理实体允许延迟加载(lazy loading)。

注意:只在 EF 6 中支持,在 EF Core 2.0 中暂时不支持。

一个简单对象实体必须满足一下条件才能成为一个简单对象代理:

  1. 一个简单对象类必须声明成 public 访问。
  2. 一个简单对象类必须不能是 sealed (在 Visual Basic 是 NotInheritable )。
  3. 一个简单对象类必须不能是 abstract (在 Visual Basic 是 MustInherit )。
  4. 每一个导航属性必须声明成 public,virtual。
  5. 每一个集合属性必须是 ICollection<T>
  6. 在上下文类中 ProxyCreationEnabled 选项不能是 false (默认是 true)。

下面的简单对象实体满足了上面的所有要求,在运行时可以变成一个动态代理实体。

public class Student
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public DateTime? DateOfBirth { get; set; }
    public byte[]  Photo { get; set; }
    public decimal Height { get; set; }
    public float Weight { get; set; }

    public virtual StudentAddress StudentAddress { get; set; }
    public virtual Grade Grade { get; set; }
}

注意:默认情况下,每一个实体的动态代理是打开的。然而,你可以在上下文类中通过设置context.Configuration.ProxyCreationEnabled = false;来关闭动态代理。
在运行时, EF API 将会为上面的 Student实体创建一个动态代理的实例。Student的动态代理类型将会是System.Data.Entity.DynamicProxies.Student,如下所示:
这里写图片描述
使用`ObjectContext.GetObjectType()可以找到被动态代理封装在底层的类型,如下所示:
这里写图片描述

实体状态

Entity States in Entity Framework:

EF API 维持每一个实体声明周期期间的状态。通过上下文对每一个实体执行操作时都会有一个状态。在 EF 6 中,实体的状态用枚举类型System.Data.Entity.EntityState表示,在 EF Core 中用枚举类型Microsoft.EntityFrameworkCore.EntityState表示。这些枚举类型有如下值:

  1. Added
  2. Modified
  3. Deleted
  4. Unchanged
  5. Detached

一旦上下文从数据库中检索数据,它就会保持所有实体对象的引用,也会保持对实体状态的跟踪维护队实体属性所作的修改。这个特性就叫做改变跟踪(Change Tracking)。

实体状态从 Unchanged 转变成 Modified 状态是唯一个由上下文自动完成情形。所有其它的改变必须显式地使用合适的DbContext 或者 DbSet中的方法。

EF API 在 context.SaveChanges()被调用时会根据实体状态创建并执行 INSERT,UPDATE,和 DELETE 命令。它对 Added 状态的实体执行 INSERT 命令,对 Modified 状态的实体执行 UPDATE 命令,对 Deleted 状态的实体执行 DELETE 命令。上下文跟踪 Detached 状态的实体。下面图表解释了状态实体的重要性:
这里写图片描述

因此,实体状态在 Entity Framework 中扮演了一个很重要的角色。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值