zoukankan      html  css  js  c++  java
  • Entity Framework入门教程(8)---预先加载、延迟加载、显示加载

    1.预先加载

    预先加载:在对一种类型的实体进行查询时,将相关的实体作为查询的一部分一起加载。预先加载可以使用Include()方法实现。

    1.加载一个相关实体类型

    栗子:使用Include()方法从数据库中获取所有学生及成绩级别。
    导航属性实现预先加载:

    using (var ctx = new SchoolDBEntities())
    {
      var stud1 = ctx.Students
              .Include("Standard")
              .Where(s => s.StudentName == "Bill")
              .FirstOrDefault<Student>();
    }

    lambda表达式实现预先加载:

    using (var ctx = new SchoolDBEntities())
    {
      var stud1 = ctx.Students.Include(s => s.Standard)
              .Where(s => s.StudentName == "Bill")
              .FirstOrDefault<Student>();
    }

    2.加载多个相关实体类型

    栗子:使用Include()方法从数据库中获取所有学生及其成绩级别和评分老师。
    导航属性实现预先加载:

    using (var ctx = new SchoolDBEntities())
    {
        var stud1 = ctx.Students.Include("Standard.Teachers")
                    .Where(s => s.StudentName == "Bill")
                 .FirstOrDefault<Student>();
    }                

    lambda表达式实现预先加载:

    using (var ctx = new SchoolDBEntities())
    {
      var stud1 = ctx.Students.Include(s => s.Standard.Teachers)
                    .Where(s => s.StudentName == "Bill")
                    .FirstOrDefault<Student>();
    }

    2.延迟加载

    1.概念

    延迟加载顾名思义就是不立即加载,而是在我们访问的时候才加载,这和预先加载刚好相反。
    一个栗子:查询Student的StudentAddress

    using (var ctx = new SchoolDBEntities())
    {
        //这里只加载student实体,导航属性StudentAddress没有加载
      IList<Student> studList = ctx.Students.ToList<Student>();
      Student std = studList[0];
    
      //只加载特定student的住址(通过一个单独的sql进行实现的)
      StudentAddress add = std.StudentAddress;
    }

    2.禁用延迟加载

    我们可以禁用特定实体或者特定context的延迟加载。去掉实体导航属性的virtual,实体就不能进行延迟加载了。也可以通过context的cofiguration实现禁用该context下所有实体的延迟加载,代码如下:

    public partial class SchoolDBEntities : DbContext
    {
        public SchoolDBEntities(): base("name=SchoolDBEntities")
        {    
            //SchoolDBEntities的所有实体都禁用延迟加载
        this.Configuration.LazyLoadingEnabled = false;
      }
      //如果去掉virtual那么Students禁用延迟加载
      public virtual DbSet<Student> Students { get; set; }
      protected override void OnModelCreating(DbModelBuilder modelBuilder){}
    }

    3.延迟加载前提

    如果要实现延迟加载,必须满足下边三个条件,缺一不可

    1.context.Configuration.ProxyCreationEnabled应为true。
    2.context.Configuration.LazyLoadingEnabled应为true。
    3.导航属性应定义为public virtual xxx,如果属性未定义为virtual,则Context不会进行延迟加载。

    3.显式加载

    1.Load方法

    即使禁用了延迟加载(在EF 6中),仍然可能延迟加载相关实体,这时可以使用Load()方法显式加载相关实体。
    一个栗子:

    using (var context = new SchoolContext())
    {
      var student = context.Students
                  .Where(s => s.FirstName == "Bill")
                  .FirstOrDefault<Student>();
    
      context.Entry(student).Reference(s => s.StudentAddress).Load(); // loads StudentAddress
      context.Entry(student).Collection(s => s.StudentCourses).Load(); // loads Courses collection 
    } 

    在上面的栗子中, context.Entry(student).Reference(s => s.StudentAddress).Load() 会加载StudentAddress实体。Reference()方法用于获取指定实体导航属性的对象,Load()方法显式加载。

    同样的方式, context.Entry(student).Collection(s => s.Courses).Load() Collection()加载student的集合导航属性Courses,Load()方法显示加载。

    2.Query方法

    有时候我们想对查询的结果在加载前进行过滤,Query()方法就可以排上用场了。
    一个栗子:查询名字为bill的学生的课程集合中数学课。

    using (var context = new SchoolContext())
    {
      var student = context.Students
                  .Where(s => s.FirstName == "Bill")
                  .FirstOrDefault<Student>();
    
      context.Entry(student)
          .Collection(s => s.StudentCourses)
          .Query()//这里不加载,下面对这一步的结果过滤
            .Where(sc => sc.CourseName == "Maths")
            .FirstOrDefault();
    } 

    在上边栗子中 .Collection(s => s.StudentCourses).Query() 不加载结果集,我们可以把Query()方法的结果看作是一个中间结果,可以对中间结果做进一步过滤。

    EF系列目录链接:Entity Franmework系列教程汇总

  • 相关阅读:
    Machine Learning/Introducing Logistic Function
    学习Machine Leaning In Action(四):逻辑回归
    极致和厚道为小米新国货的核心实质(极致不是指最好的,而是要超乎预期)
    做事要提前留有余地,否则到时候就来不及了(超市买菜,找工作,交朋友,发脾气都是如此)
    UpdateWindow API函数的作用很明显
    近几年前端技术盘点以及 2016 年技术发展方向
    使用SetLocaleInfo设置时间后必须调用广播WM_SETTINGCHANGE,通知其他程序格式已经更改
    设计模式——(Abstract Factory)抽象工厂
    从优化到再优化,最长公共子串
    与数据库打交道的Adapter----SimpleCursorAdapter
  • 原文地址:https://www.cnblogs.com/wyy1234/p/9629502.html
Copyright © 2011-2022 走看看