首页 > 代码库 > 学习EF之贪婪加载和延迟加载

学习EF之贪婪加载和延迟加载

从暑假开始接触code first以来,一直感觉很好用,主要在于开发过程中以业务为中心可以随时修改数据模型生成数据库,还有一个原因就是查询起来很方便

这里找了一个以前database first的一段代码

        public IEnumerable<Category> GetParAndGrand(int id)        {            var par = db.Category.Find(db.Category.Find(id).ParentId);            if(par.Id == id)            {                par = null;            }            var grand = new Category();            if(par != null)            {                grand = db.Category.Find(par.ParentId);            }            var l = new List<Category>();            if(par != null)                l.Add(par);            if (par != null && grand.Id != par.Id)                l.Add(grand);            return l;        }

这段代码的主要意思是给出一个Category的Id,找出它的父节点和爷节点,由于database first生成的edmx不能使用延迟加载和贪婪加载,这里只能每次按Id重新到数据库查找.

下面学习一下贪婪加载

 public class EFDbContext : DbContext    {        public EFDbContext() : base("DefaultConnection")         {        }        public DbSet<Category> Categories { get; set; }        public DbSet<Article> Articles { get; set; }    }    public class Category    {        public int Id { get; set; }        public string Name { get; set; }        public ICollection<Article> Articles { get; set; }    }    public class Article    {        public int Id { get; set; }        public string Title { get; set; }        public Category Category { get; set; }    }

 先添加两条数据

            var context = new EFDbContext();            var category = new Category() { Name = "类别1" };            category = context.Categories.Add(category);            var article = new Article() { Category = category, Title = "标题" };            context.Articles.Add(article);            var category2 = new Category() { Name = "类别2" };            category2 = context.Categories.Add(category2);            var article2 = new Article() { Category = category2, Title = "标题2" };            context.Articles.Add(article2);            context.SaveChanges();

 注意观察红色线条

技术分享

延迟加载

  public class EFDbContext : DbContext    {        public EFDbContext() : base("DefaultConnection")         {        }        public DbSet<Category> Categories { get; set; }        public DbSet<Article> Articles { get; set; }    }    public class Category    {        public int Id { get; set; }        public string Name { get; set; }        public virtual ICollection<Article> Articles { get; set; }    }    public class Article    {        public int Id { get; set; }        public string Title { get; set; }        public virtual Category Category { get; set; }    }

 指的注意的是,这里有处与刚刚不同,关联对象前添加了 virtual 关键字

技术分享

在上下文构造函数中添加这一句话就可以关闭延迟加载

this.Configuration.LazyLoadingEnabled = false;

关闭延迟加载后,仍然可以使用Include方法贪婪加载

 今天弄到这么晚,还有一个原因就是发现了一个bug,在前面可以看到我搜索Article在FirstOrDefault中加了一个条件,假如去掉这个条件,在贪婪加载中不用Include方法,此时找到的两个对象的关联对象都不是null,不知道强大的EF是怎么发现他们的关联的,还请大家不吝赐教

 

学习EF之贪婪加载和延迟加载