2015-01-20 45 views
0

我想先學使用VS 2013實體框架6多對多的代碼首先急切加載爲遞歸結果

我在做同樣的事情在這個問題實體框架6碼:How to eagerly load a many to many relationship with the entity framework code first?

使用相同的設置

public class Student 
{ 
    public int Id {get;set} 
    public string FullName {get;set;} 
    public virtual ICollection<Course> Courses {get;set;} 
} 

public class Course 
{ 
    public int Id {get;set;} 
    public string FullName {get;set;} 
    public virtual ICollection<Student> Students {get;set;} 
} 

而答案

var allStudents = context.Students.Include(s => s.Courses); 

但是當調試我得到一個遞歸結果。 每一個學生包含課程的列表,這些課程包含學生的名單,其中包含課程,包含學生等等....

同樣的事情,而無需使用方法.Include(...

var allStudents = context.Students; 

我在一家腳手架MVC 5 ApiController會拋出使用此:

System.Runtime.Serialization.SerializationException

卸下Virtual從模型和仍在使用.Include(...拋出:對於類型

對象圖「SchoolEF.Models.Course」包含週期 並且如果參考跟蹤被禁止不能被序列化。

我想我還沒有完全理解如何做急切的加載和如何使用.Include()方法。

回答

0

您正在使用include方法。 EF正在返回一個具有引用的課程對象的Student對象。此課程對象還引用了Student對象,因此您有循環引用。

這就是EF設計的工作原理,如果您手動創建對象層次結構,則會得到相同的效果。例如

public void ReferenceLoop_CheckAreEqual() 
{ 
    Student student = new Student(); 
    Course course = new Course(); 

    student.Course = course; 
    course.Student = student; 

    //This is now allowed 
    course.Student.Course.Student.Course; 

    Assert.IsTrue(Object.ReferenceEquals(course, course.Student.Course.Student.Course); 
} 

從讀您的文章我認爲這個問題是你試圖從asp.net的MVC返回的對象時,得到一個序列化錯誤。

有(至少)三種方法可以解決這個問題。

1)禁用延遲加載

在您的EF上下文設置添加this.Configuration.LazyLoadingEnabled = false;會自動阻止加載子屬性EF,所以除非你明確地包括他們,他們會null

這不是最好的方法,因爲延遲加載可能在項目的其他部分有價值。

2)設置Course.Student爲空

var allStudents = context.Students.Include(s => s.Courses); 
foreach (Student student in allStudents) 
{ 
    student.Course.Student = null; 
} 

這是一個黑客位

3)告訴你序列化器如何處理的參考循環

你不提的其您正在使用的序列化程序,但大多數應該能夠以某種方式處理參考循環。 This msdn blog演示如何在使用Newtonsoft的JSON序列化程序時執行此操作。

+0

好的答案,但是ID必須不同意懶惰加載可能是有價值的評論,個人而言,它對人類造成了一場災難,並且導致更多的問題,然後它解決了 – 2015-01-20 23:30:58

+0

我已經更新了可以_could_。我傾向於同意你的觀點,我總是禁用它,但在一些情況下它必須是有用的...... – 2015-01-20 23:43:26

+0

我已經知道我有2個不同的問題,這要歸功於這個答案和建議的[MSDN博客](http ://blogs.msdn.com/b/hongyes/archive/2012/09/04/loop-reference-handling-in-serializer.aspx) 解決方案是禁用LazyLoading並插入'config.Formatters.JsonFormatter.SerializerSettings .ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;'到WebApiConfig.cs – nobee 2015-01-21 00:36:56

0

如果我正確地讀你的問題

你需要開啓延遲加載關閉

this.ContextOptions.LazyLoadingEnabled = false; 

在你的DbContext

構造,使更精細的控制得到了什麼加載並使用時include