Entity framework有3种加载数据的方式:懒汉式(Lazy loading),饿汉式(Eager loading),显示加载(Explicit loading)。3种加载方式有各自的优缺点,详细的可以参考微软的技术文章《Reading Related Data with the Entity Framework in an ASP.NET MVC Application
本文只针对需要一次性加载多个相关联实体的情况进行讨论。
 
1. 数据库模型
 
 
2. Model和DbContext
 
 public class Student
{
public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime? EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Student.cs

 public class Enrollment
{
public int EnrollmentID { get; set; } public int CourseID { get; set; } public int StudentID { get; set; } public int? Grade { get; set; } public virtual Student Student { get; set; } public virtual Course Course { get; set; }
}

Enrollment.cs

 public class Course
{
public int CourseID { get; set; } public string Title { get; set; } public string Credits { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Course

 public class Context:DbContext
{
public Context() : base("ReadMultipleEntity")
{ } public DbSet<Student> Students { get; set; } public DbSet<Course> Courses { get; set; } public DbSet<Enrollment> Enrollments { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
} }

Context.cs

 
3. 需求
 
想要得到所有学生及其选课名称的列表
因为是想要所有学生及课程的列表信息,所以此时选择饿汉式效率最佳(一次性将所有数据加载到内存)。
context.Students.Include(x => x.Enrollments).ToList();//加载Students和Enrollments实体
 
通过Sql Profiler监控到所执行的SQL
 SELECT
[Project1].[ID] AS [ID],
[Project1].[LastName] AS [LastName],
[Project1].[FirstMidName] AS [FirstMidName],
[Project1].[EnrollmentDate] AS [EnrollmentDate],
[Project1].[C1] AS [C1],
[Project1].[EnrollmentID] AS [EnrollmentID],
[Project1].[CourseID] AS [CourseID],
[Project1].[StudentID] AS [StudentID],
[Project1].[Grade] AS [Grade]
FROM ( SELECT
[Extent1].[ID] AS [ID],
[Extent1].[LastName] AS [LastName],
[Extent1].[FirstMidName] AS [FirstMidName],
[Extent1].[EnrollmentDate] AS [EnrollmentDate],
[Extent2].[EnrollmentID] AS [EnrollmentID],
[Extent2].[CourseID] AS [CourseID],
[Extent2].[StudentID] AS [StudentID],
[Extent2].[Grade] AS [Grade],
CASE WHEN ([Extent2].[EnrollmentID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
FROM [dbo].[Student] AS [Extent1]
LEFT OUTER JOIN [dbo].[Enrollment] AS [Extent2] ON [Extent1].[ID] = [Extent2].[StudentID]
) AS [Project1]
ORDER BY [Project1].[ID] ASC, [Project1].[C1] ASC

Only Enrollment

如果想将和Enrollment相关联的Course实体同时加载,则需要如下语句:
context.Students.Include(x => x.Enrollments.Select(y => y.Course)).ToList();
 
通过Sql Profiler监控到所执行的SQL
 SELECT
[Project1].[ID] AS [ID],
[Project1].[LastName] AS [LastName],
[Project1].[FirstMidName] AS [FirstMidName],
[Project1].[EnrollmentDate] AS [EnrollmentDate],
[Project1].[C1] AS [C1],
[Project1].[EnrollmentID] AS [EnrollmentID],
[Project1].[CourseID] AS [CourseID],
[Project1].[StudentID] AS [StudentID],
[Project1].[Grade] AS [Grade],
[Project1].[CourseID1] AS [CourseID1],
[Project1].[Title] AS [Title],
[Project1].[Credits] AS [Credits]
FROM ( SELECT
[Extent1].[ID] AS [ID],
[Extent1].[LastName] AS [LastName],
[Extent1].[FirstMidName] AS [FirstMidName],
[Extent1].[EnrollmentDate] AS [EnrollmentDate],
[Join1].[EnrollmentID] AS [EnrollmentID],
[Join1].[CourseID1] AS [CourseID],
[Join1].[StudentID] AS [StudentID],
[Join1].[Grade] AS [Grade],
[Join1].[CourseID2] AS [CourseID1],
[Join1].[Title] AS [Title],
[Join1].[Credits] AS [Credits],
CASE WHEN ([Join1].[EnrollmentID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
FROM [dbo].[Student] AS [Extent1]
LEFT OUTER JOIN (SELECT [Extent2].[EnrollmentID] AS [EnrollmentID], [Extent2].[CourseID] AS [CourseID1], [Extent2].[StudentID] AS [StudentID], [Extent2].[Grade] AS [Grade], [Extent3].[CourseID] AS [CourseID2], [Extent3].[Title] AS [Title], [Extent3].[Credits] AS [Credits]
FROM [dbo].[Enrollment] AS [Extent2]
INNER JOIN [dbo].[Course] AS [Extent3] ON [Extent2].[CourseID] = [Extent3].[CourseID] ) AS [Join1] ON [Extent1].[ID] = [Join1].[StudentID]
) AS [Project1]
ORDER BY [Project1].[ID] ASC, [Project1].[C1] ASC

Enrollment and Course

比较两次SQL可得,后者多join了一个Course表,从而一次性得到所有的结果。如果想在Course再连接其他实体,可以仿照上面的形式。
 
 
 

Entity framework 加载多层相关实体数据的更多相关文章

  1. Entity Framework加载相关实体——延迟加载Lazy Loading、贪婪加载Eager Loading、显示加载Explicit Loading

    Entity Framework提供了三种加载相关实体的方法:Lazy Loading,Eager Loading和Explicit Loading.首先我们先来看一下MSDN对三种加载实体方法的定义 ...

  2. Entity Framework加载数据的三种方式。

    MSDN文章Loading Related Entities 有 Eagerly Loading Lazy Loading Explicitly Loading 三种方式. 而看到查询中包含Inclu ...

  3. [Programming Entity Framework] 第3章 查询实体数据模型(EDM)(一)

    http://www.cnblogs.com/sansi/archive/2012/10/18/2729337.html Programming Entity Framework 第二版翻译索引 你可 ...

  4. Smart3D系列教程7之 《手动配置S3C索引加载全部的瓦片数据》

    一.前言 迄今为止,Wish3D已经出品推出了6篇系列教程,从倾斜摄影的原理方法.采集照片的技巧.Smart3D各模块的功能应用.小物件的照片重建.大区域的地形重建到DSM及正射影像的处理生产,立足于 ...

  5. KnockoutJS 3.X API 第七章 其他技术(1) 加载和保存JSON数据

    Knockout允许您实现复杂的客户端交互性,但几乎所有Web应用程序还需要与服务器交换数据,或至少将本地存储的数据序列化. 最方便的交换或存储数据的方式是JSON格式 - 大多数Ajax应用程序今天 ...

  6. Knockout应用开发指南 第六章:加载或保存JSON数据

    原文:Knockout应用开发指南 第六章:加载或保存JSON数据 加载或保存JSON数据 Knockout可以实现很复杂的客户端交互,但是几乎所有的web应用程序都要和服务器端交换数据(至少为了本地 ...

  7. 第六章:加载或保存JSON数据

    加载或保存JSON数据 Knockout可以实现很复杂的客户端交互,但是几乎所有的web应用程序都要和服务器端交换数据(至少为了本地存储需要序列化数据),交换数据最方便的就是使用JSON格式 – 大多 ...

  8. 模块 DLL C:\WINDOWS\system32\inetsrv\aspnetcore.dll 未能加载。返回的数据为错误信息。

    更新了win10的版本后,就启动原来的iis发布的程序 程序池就自动关闭.后来 启动网站 iis程序池自动关闭. 在为应用程序池“.NET v4.5”提供服务的工作进程“21908”中,协议“http ...

  9. jqgrid 分页时,清空原表格数据加载返回的新数据

    由于,我们是动态分页,分页后的数据是在触发分页后动态加载而来.如何使jqgrid清空原数据而加载新数据? 1)调用jqgrid的 clearGridData 方法清空表格数据 2)调用jqgrid的  ...

随机推荐

  1. "被删除的文本"组件:<del> —— 快应用组件库H-UI

     <import name="del" src="../Common/ui/h-ui/text/c_tag_del"></import> ...

  2. 实战if-else 过多详解

    1.本文实例代码仅仅是俩个小例子. package com.example.demo.pattern.ifElse; import java.util.HashMap; import java.uti ...

  3. 使用基于vuecli创建的目录推送到指定远程分支

    笔者使用vuecli创建项目目录以后,在想将该目录提交到远程仓库时发现行不通,在忙活了一下午以后写下此文 1.github上新建一空分支,然后克隆该分支地址:  https://github.com/ ...

  4. jpa是什么,和hibernate 有什么关系

    JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中.JPA 的目标之一是制定一个可以由很多供应商实现的API,并且开发人员可以编码来实现该API,而不 ...

  5. Eureka源码分析

    源码流程图 先上图,不太清晰,抱歉 一.Eureka Server源码分析 从@EnableEurekaServer注解为入口,它是一个标记注解,点进去看 注解内容如下 /** * 激活Eureka服 ...

  6. 必须先理解的RocketMQ入门手册,才能再次深入解读

    RocketMQ入门手册 RocketMQ是一个分布式.队列模型的开源消息中间件,前身是MetaQ,是阿里研发的一个队列模型的消息中间件,后开源给apache基金会成为了apache的顶级开源项目,具 ...

  7. MySQL主从复制,主主复制,半同步复制

    实验环境: 系统:CentOS Linux release 7.4.1708 (Core) mariadb:mariadb-server-5.5.56-2.el7.x86_64 node1:172.1 ...

  8. 为什么redis是单线程的以及为什么这么快?

    官网的说法 我们先来认真看一下官网的说法.翻译过来大意如下: CPU并不是您使用Redis的瓶颈,因为通常Redis要么受内存限制,要么受网络限制.例如,使用在一般Linux系统上运行的流水线Redi ...

  9. 三本毕业(非科班),四次阿里巴巴面试,终拿 offer(大厂面经)

    作者:gauseen 原文:https://github.com/gauseen/blog 公众号:「学前端」,只搞技术不搞广告文,欢迎关注~ 第一次 20:00 电话一面 - 自我介绍 - 对公司工 ...

  10. python正则表达式详解之Match类及其方法

    1.Match对象简介 match对象通常是由正则表达式对象的match 方法,search 方法等经过匹配之后而产生.可以直接当做bool值使用,如果匹配则相当于True, 如果不匹配,则返回Non ...