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 }
7
View 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 }
8
View Code