預先加載:在對一種類型的實體進行查詢時,將相關的實體做爲查詢的一部分一塊兒加載。預先加載能夠使用Include()方法實現。html
栗子:使用Include()方法從數據庫中獲取全部學生及成績級別。
導航屬性實現預先加載:sql
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>(); }
栗子:使用Include()方法從數據庫中獲取全部學生及其成績級別和評分老師。
導航屬性實現預先加載:ide
using (var ctx = new SchoolDBEntities()) { var stud1 = ctx.Students.Include("Standard.Teachers") .Where(s => s.StudentName == "Bill") .FirstOrDefault<Student>(); }
lambda表達式實現預先加載:post
using (var ctx = new SchoolDBEntities()) { var stud1 = ctx.Students.Include(s => s.Standard.Teachers) .Where(s => s.StudentName == "Bill") .FirstOrDefault<Student>(); }
延遲加載顧名思義就是不當即加載,而是在咱們訪問的時候才加載,這和預先加載恰好相反。
一個栗子:查詢Student的StudentAddressui
using (var ctx = new SchoolDBEntities()) { //這裏只加載student實體,導航屬性StudentAddress沒有加載 IList<Student> studList = ctx.Students.ToList<Student>(); Student std = studList[0]; //只加載特定student的住址(經過一個單獨的sql進行實現的) StudentAddress add = std.StudentAddress; }
咱們能夠禁用特定實體或者特定context的延遲加載。去掉實體導航屬性的virtual,實體就不能進行延遲加載了。也能夠經過context的cofiguration實現禁用該context下全部實體的延遲加載,代碼以下:this
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){} }
若是要實現延遲加載,必須知足下邊三個條件,缺一不可spa
1.context.Configuration.ProxyCreationEnabled應爲true。 2.context.Configuration.LazyLoadingEnabled應爲true。 3.導航屬性應定義爲public virtual xxx,若是屬性未定義爲virtual,則Context不會進行延遲加載。
即便禁用了延遲加載(在EF 6中),仍然可能延遲加載相關實體,這時能夠使用Load()方法顯式加載相關實體。
一個栗子:code
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()方法顯式加載。htm
一樣的方式, context.Entry(student).Collection(s => s.Courses).Load() Collection()加載student的集合導航屬性Courses,Load()方法顯示加載。
有時候咱們想對查詢的結果在加載前進行過濾,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系列教程彙總