DBContext:
在之前的章節《創建實體數據模型》中,EDM為我們創建了SchoolDBEntities 類,它派生子System.Data.Entity.DbContext這個類,這個DbContext在EF中被稱作上下文類。
在EF4.1之前,EDM生成的上下文類是派生自ObjectContext這個類的。它有點難於使用。DbContext 在概念上類似於ObjectContext。DbContext 只是對ObjectContext 進行了封裝使其更容易在所有開發場景中使用。(如Code First, Model First 和 Database First 中)
DbContext 是EF中重要的一環,它是數據庫與你應用程序域或實體類的橋梁。
DbContext 是負責數據與對象互操作的主要的類型。它主要負責以下一些動作:
EntitySet : DbContext 包含所有從數據庫表中被映射出來的實體對象的集合(如DbSet<TEntity>)。
Querying : DbContext 將LINQ To Entities 轉化為SQL 查詢語句並發送至數據庫。
Change Tracking : 它保持變更追蹤,一旦實體對象發生改變它就會從數據庫中進行查詢。
Persisting Data : 它也可以基於實體狀態對數據庫進行插入,更新和刪除操作。
Caching : DbContext 默認作一級緩存,它存儲在上下文類的生命周期中檢索過的實體對象。
Manage Relationship : 在DB-First 或 Model-First 中 DbContext 使用CSDL, MSL 和 SSDL 管理關系,在Code-First中使用流式API管理關系。
Object Materialization : DbContext 將原始的表數據轉化至實體對象中。
以下例子中的SchoolDBEntities 類是又EDM根據SchoolDB數據庫創建的
1 namespace EFTutorials 2 { 3 using System; 4 using System.Data.Entity; 5 using System.Data.Entity.Infrastructure; 6 using System.Data.Entity.Core.Objects; 7 using System.Linq; 8 9 public partial class SchoolDBEntities : DbContext 10 { 11 public SchoolDBEntities() 12 : base("name=SchoolDBEntities") 13 { 14 } 15 16 protected override void OnModelCreating(DbModelBuilder modelBuilder) 17 { 18 throw new UnintentionalCodeFirstException(); 19 } 20 21 public virtual DbSet<Course> Courses { get; set; } 22 public virtual DbSet<Standard> Standards { get; set; } 23 public virtual DbSet<Student> Students { get; set; } 24 public virtual DbSet<StudentAddress> StudentAddresses { get; set; } 25 public virtual DbSet<Teacher> Teachers { get; set; } 26 public virtual DbSet<View_StudentCourse> View_StudentCourse { get; set; } 27 28 public virtual ObjectResult<GetCoursesByStudentId_Result> GetCoursesByStudentId(Nullable<int> studentId) 29 { 30 var studentIdParameter = studentId.HasValue ? 31 new ObjectParameter("StudentId", studentId) : 32 new ObjectParameter("StudentId", typeof(int)); 33 34 return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<GetCoursesByStudentId_Result>("GetCoursesByStudentId", studentIdParameter); 35 } 36 37 public virtual int sp_DeleteStudent(Nullable<int> studentId) 38 { 39 var studentIdParameter = studentId.HasValue ? 40 new ObjectParameter("StudentId", studentId) : 41 new ObjectParameter("StudentId", typeof(int)); 42 43 return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("sp_DeleteStudent", studentIdParameter); 44 } 45 46 public virtual ObjectResult<Nullable<decimal>> sp_InsertStudentInfo(Nullable<int> standardId, string studentName) 47 { 48 var standardIdParameter = standardId.HasValue ? 49 new ObjectParameter("StandardId", standardId) : 50 new ("StandardId", typeof(int)); 51 52 var studentNameParameter = studentName != null ? 53 new ObjectParameter("StudentName", studentName) : 54 new ObjectParameter("StudentName", typeof(string)); 55 56 return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<Nullable<decimal>>("sp_InsertStudentInfo", standardIdParameter, studentNameParameter); 57 } 58 59 public virtual int sp_UpdateStudent(Nullable<int> studentId, Nullable<int> standardId, string studentName) 60 { 61 var studentIdParameter = studentId.HasValue ? 62 new ObjectParameter("StudentId", studentId) : 63 new ObjectParameter("StudentId", typeof(int)); 64 65 var standardIdParameter = standardId.HasValue ? 66 new ObjectParameter("StandardId", standardId) : 67 new ObjectParameter("StandardId", typeof(int)); 68 69 var studentNameParameter = studentName != null ? 70 new ObjectParameter("StudentName", studentName) : 71 new ObjectParameter("StudentName", typeof(string)); 72 73 return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("sp_UpdateStudent", studentIdParameter, standardIdParameter, studentNameParameter); 74 } 75 } 76 }View Code
你可以通過上面的例子看出context 類包含類型為DbSet<TEntity>的所有實體集合。也包含EDM中存儲過程及視圖所對應的函數。
Context 類重寫了 OnModelCreating 方法,參數DbModelBuilder 提供流式API來配置Code-First中實體的關系。
實例化 DbContext:
實例化DbContext 來執行CRUD操作。
1 2 using (var ctx = new SchoolDBEntities()) 3 { 4 5 //在這裡執行CRUD操作.. 6 } 7View Code
從DbContext 中獲取ObjectContext :
在常見的任務中DBContext 中的API 相較於ObjectContext 的API 而言更加容易使用。當然你也可以從DBContext 中獲取ObjectContext 的引用來使用其中的一些方法。可以同過IObjectContextAdpter 來完成。
1 2 using (var ctx = new SchoolDBEntities()) 3 { 4 var objectContext = (ctx as System.Data.Entity.Infrastructure.IObjectContextAdapter).ObjectContext; 5 6 //在這裡使用objectContext.. 7 } 8View Code