1. 程式人生 > >Entity framework 加載多層相關實體數據

Entity framework 加載多層相關實體數據

ide date .com microsoft image sql art mic when

Entity framework有3種加載數據的方式:懶漢式(Lazy loading),餓漢式(Eager loading),顯示加載(Explicit loading)。3種加載方式有各自的優缺點,詳細的可以參考微軟的技術文章《Reading Related Data with the Entity Framework in an ASP.NET MVC Application》 本文只針對需要一次性加載多個相關聯實體的情況進行討論。 1. 數據庫模型 技術分享 2. Model和DbContext 技術分享
 1 public class Student
 2     {
 3         public
int ID { get; set; } 4 5 public string LastName { get; set; } 6 7 public string FirstMidName { get; set; } 8 9 public DateTime? EnrollmentDate { get; set; } 10 11 public virtual ICollection<Enrollment> Enrollments { get; set; } 12 }
Student.cs 技術分享
 1
public class Enrollment 2 { 3 public int EnrollmentID { get; set; } 4 5 public int CourseID { get; set; } 6 7 public int StudentID { get; set; } 8 9 public int? Grade { get; set; } 10 11 public virtual Student Student { get; set; } 12 13 public
virtual Course Course { get; set; } 14 }
Enrollment.cs 技術分享
 1 public class Course
 2     {
 3         public int CourseID { get; set; }
 4 
 5         public string Title { get; set; }
 6 
 7         public string Credits { get; set; }
 8 
 9         public virtual ICollection<Enrollment> Enrollments { get; set; }
10     }
Course 技術分享
 1 public class Context:DbContext
 2     {
 3         public Context() : base("ReadMultipleEntity")
 4         {
 5 
 6         }
 7 
 8         public DbSet<Student> Students { get; set; }
 9 
10         public DbSet<Course> Courses { get; set; }
11 
12         public DbSet<Enrollment> Enrollments { get; set; }
13 
14         protected override void OnModelCreating(DbModelBuilder modelBuilder)
15         {
16             modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
17         }
18 
19     }
Context.cs 3. 需求 想要得到所有學生及其選課名稱的列表 因為是想要所有學生及課程的列表信息,所以此時選擇餓漢式效率最佳(一次性將所有數據加載到內存)。 context.Students.Include(x => x.Enrollments).ToList();//加載Students和Enrollments實體 通過Sql Profiler監控到所執行的SQL 技術分享
 1 SELECT 
 2     [Project1].[ID] AS [ID], 
 3     [Project1].[LastName] AS [LastName], 
 4     [Project1].[FirstMidName] AS [FirstMidName], 
 5     [Project1].[EnrollmentDate] AS [EnrollmentDate], 
 6     [Project1].[C1] AS [C1], 
 7     [Project1].[EnrollmentID] AS [EnrollmentID], 
 8     [Project1].[CourseID] AS [CourseID], 
 9     [Project1].[StudentID] AS [StudentID], 
10     [Project1].[Grade] AS [Grade]
11     FROM ( SELECT 
12         [Extent1].[ID] AS [ID], 
13         [Extent1].[LastName] AS [LastName], 
14         [Extent1].[FirstMidName] AS [FirstMidName], 
15         [Extent1].[EnrollmentDate] AS [EnrollmentDate], 
16         [Extent2].[EnrollmentID] AS [EnrollmentID], 
17         [Extent2].[CourseID] AS [CourseID], 
18         [Extent2].[StudentID] AS [StudentID], 
19         [Extent2].[Grade] AS [Grade], 
20         CASE WHEN ([Extent2].[EnrollmentID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
21         FROM  [dbo].[Student] AS [Extent1]
22         LEFT OUTER JOIN [dbo].[Enrollment] AS [Extent2] ON [Extent1].[ID] = [Extent2].[StudentID]
23     )  AS [Project1]
24     ORDER BY [Project1].[ID] ASC, [Project1].[C1] ASC
Only Enrollment

如果想將和Enrollment相關聯的Course實體同時加載,則需要如下語句: context.Students.Include(x => x.Enrollments.Select(y => y.Course)).ToList(); 通過Sql Profiler監控到所執行的SQL 技術分享
 1 SELECT 
 2     [Project1].[ID] AS [ID], 
 3     [Project1].[LastName] AS [LastName], 
 4     [Project1].[FirstMidName] AS [FirstMidName], 
 5     [Project1].[EnrollmentDate] AS [EnrollmentDate], 
 6     [Project1].[C1] AS [C1], 
 7     [Project1].[EnrollmentID] AS [EnrollmentID], 
 8     [Project1].[CourseID] AS [CourseID], 
 9     [Project1].[StudentID] AS [StudentID], 
10     [Project1].[Grade] AS [Grade], 
11     [Project1].[CourseID1] AS [CourseID1], 
12     [Project1].[Title] AS [Title], 
13     [Project1].[Credits] AS [Credits]
14     FROM ( SELECT 
15         [Extent1].[ID] AS [ID], 
16         [Extent1].[LastName] AS [LastName], 
17         [Extent1].[FirstMidName] AS [FirstMidName], 
18         [Extent1].[EnrollmentDate] AS [EnrollmentDate], 
19         [Join1].[EnrollmentID] AS [EnrollmentID], 
20         [Join1].[CourseID1] AS [CourseID], 
21         [Join1].[StudentID] AS [StudentID], 
22         [Join1].[Grade] AS [Grade], 
23         [Join1].[CourseID2] AS [CourseID1], 
24         [Join1].[Title] AS [Title], 
25         [Join1].[Credits] AS [Credits], 
26         CASE WHEN ([Join1].[EnrollmentID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
27         FROM  [dbo].[Student] AS [Extent1]
28         LEFT OUTER JOIN  (SELECT [Extent2].[EnrollmentID] AS [EnrollmentID], [Extent2].[CourseID] AS [CourseID1], [Extent2].[StudentID] AS [StudentID], [Extent2].[Grade] AS [Grade], [Extent3].[CourseID] AS [CourseID2], [Extent3].[Title] AS [Title], [Extent3].[Credits] AS [Credits]
29             FROM  [dbo].[Enrollment] AS [Extent2]
30             INNER JOIN [dbo].[Course] AS [Extent3] ON [Extent2].[CourseID] = [Extent3].[CourseID] ) AS [Join1] ON [Extent1].[ID] = [Join1].[StudentID]
31     )  AS [Project1]
32     ORDER BY [Project1].[ID] ASC, [Project1].[C1] ASC
Enrollment and Course

比較兩次SQL可得,後者多join了一個Course表,從而一次性得到所有的結果。如果想在Course再連接其他實體,可以仿照上面的形式。 源碼參考

Entity framework 加載多層相關實體數據