一、EF延迟加载技术分为:贪婪加载和延迟加载
- 贪婪加载:(inner join)顾名思议就是把所有要加载的东西一 次性读取
//当读取订单信息orders的时候,我们希望把订单的详细信息也读取出来,那么这里我们使用Include关键字将关联表也加载进 来。
//适合小数据连接查询,也就是说执行链接sql语句
using (var context = new MyDbContext())
{
var orders = from o in context.Orders.Include("OrderDetails") select o;
}
- 延迟加载:即当我们需要用到的时候才进行加载(读取)
- 当我们希望浏览某条订单信息的时候,才显示其对应的订单详细记录时,我们希望使用延迟加载来实现,这样不仅加快的了 读取的效率,同时也避免加载不需要的数据。延迟加载通常用于foreach循环读取数据时。
//IQueryable<Customers>得益于此集合
IQueryable<Customers> customers = from data in modelData.Customers select data;
foreach(var item in customers){ //用到数据才进行连接数据库查询‘in *’ }
//延迟加载02 导航属性关联的表的数据 延迟加载 foreach循环中in执行查询
foreach (var item in customers)
{
//只查询顾客,订单表也可以拿来用(其实不存在,因为导航属性的原因,会自动帮我们查询使用)
foreach (var temp in item.Orders)
{
Console.WriteLine(temp.Oid + " " + temp.ODate);
}
}
- 禁止使用延迟加载: 在DbContext类的构造方法中声明
1 public class MyDbContext:DbContext
2 {
3 public MyDbContext()
4 {
5 this.Configuration.LazyLoadingEnabled = false;
6 }
7 }
- 导航属性应用下的多表查询:
//自动分解连接查询,两个大表分开查询,提高了执行效率,内存使用临时表,减少死锁问题发生,适合大数据量表的链接查询
//和Include("Orders")应用场景相反
foreach (var item in customers)
{
//只查询顾客,订单表也可以拿来用(其实不存在,因为导航属性的原因,会自动帮我们查询使用)
foreach (var temp in item.Orders)
{
Console.WriteLine(temp.Oid + " " + temp.ODate);
}
}
延迟加载技术总结
- 贪婪加载: 1、减少数据访问的延迟,在一次数据库的访问中返回所有的数据。 2、一次性读取所有相关的数据,可能导致部分数据实际无需用到,从而导致读取数据的速度变慢,效率变低。
- 延迟加载: 1、只在需要读取关联数据的时候才进行加载 2、可能因为数据访问的延迟而降低性能,因为循环中,每一条数据都会访问一次数据库,导致数据库的压力加大。
- 所以:如果是在foreach循环中加载数据,那么使用延迟加载会比较好, 因为不需要一次性将所有数据读取出来,这样虽然有可能会造成n次数据库的查询,但 是基本上在可以接受的范围内。
- 如果在开发时就可以预见需要一次性加载所有的数据,包含关联表的所有数据, 那么使用使用贪婪加载是比较好的选择,但是此种方式会导致效率问题,特别是数据量大的情况下。
- 通过使用include,我们可以实现查询一次数据库即可,相当于之前的inner join。如果关联多个表,可以使用多个include进行关联。
二、导航属性的应用实例:
在EF中,外键被称为导航属性,指向外键的对象,或者集合,两表关系的链接桥梁指定外键后,可以帮你做查询和延迟加载
>.数据多表关联插入:
- 通过导航属性赋值 指定主表对应 数据
- 执行操作的时候先执行主表数据,再添加外键表的数据,否则引用无效(不存在主键Id)
实例02_多表关联插入:
ModelDataContainer modelData = new ModelDataContainer();
#region 关联表插入 导航属性
//创建一个顾客实体
Customers customers = new Customers();
customers.CtmName = "张三";
customers.CtmPhone = "02151515151";
modelData.Customers.Add(customers);
customers.Orders = objOrder;//添加当前顾客的订单信息(插入订单表)
//创建两个实体
Orders orders = new Orders();
orders.ODate = "2019/06/02";
modelData.Orders.Add(orders);
Orders orders2 = new Orders();
orders2.ODate = "2019/06/03";
modelData.Orders.Add(orders2);
//关联三个实体
customers.Orders.Add(orders);
orders2.Customers = customers;//订单表添加顾客实体(顾客Id)
#endregion