2017-10-05 73 views
1

我正在開發一個測試應用程序使用ASP.Net MVC 5,實體框架與SQL Server。序列化對象時檢測到循環引用+ ASP.net mvc5 +實體框架

在我的方案中,數據庫中有2個表。 StudentQualification。 一個學生有一個或多個資格。

我需要給studentID和Student(導航性能)的Qualification列表,從數據庫中獲取一個student應該包含所有他或她有資格。

我實施的控制器方法如下。

 public JsonResult getStudentInfo(int studentId) 
    { 
     db.Configuration.ProxyCreationEnabled = false; 
     Student ss = (Student) (from s in db.Students where s.Id == studentId select s).FirstOrDefault(); 
     ss.Qualifications = (from q in db.Qualifications where q.StudentId == ss.Id select q).ToList(); 
     return Json(ss, JsonRequestBehavior.AllowGet); 
    } 

但是當我試圖調用這個函數時,它顯示這個錯誤。

A circular reference was detected while serializing an object of type 'App1.Models.Student'.

如何來解決這個問題。 我需要通過Student實例的資格完整列表。

我的學生模型類,如下所示

public partial class Student 
{ 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 
    public Student() 
    { 
     this.Qualifications = new HashSet<Qualification>(); 
    } 

    public int Id { get; set; } 
    public string Name { get; set; } 
    public Nullable<int> Age { get; set; } 
    public Nullable<byte> Gender { get; set; } 
    public string City { get; set; } 

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
    public virtual ICollection<Qualification> Qualifications { get; set; } 
} 

Qualification Model類如下

public partial class Qualification 
{ 
    public int Id { get; set; } 
    public Nullable<int> StudentId { get; set; } 
    public string QualificationName { get; set; } 
    public string Institute { get; set; } 
    public Nullable<System.DateTime> EffectiveDate { get; set; } 

    public virtual Student Student { get; set; } 
} 

上述模型類已通過實體數據模型生成的。 我遵循數據庫第一方法..

在此先感謝。

+0

Qualification類是什麼樣的? – Robert

+0

@羅伯特對不起。我剛更新了這個問題。 – JayNaz

+0

是的......我猜羅伯特猜對了;學生 - > qualification->的學生。是你的循環參考。在過去,我編寫代碼將Student.Qualification.Student設置爲null,這樣就不會發生這種情況。我相信有更好的解決方案。我不知道它是否可以解決這個問題,但你可以試試這個庫:https://github.com/zzzprojects/GraphDiff – theGleep

回答

1

兩件事情:

  1. 我以前可空位爲性別類型從Student類,而不是byte
  2. 你說過一個學生有一個或多個資格,但你沒有提到同一個資格可以在不同的學生之間分享。如果那麼您需要第三個表StudentQualification來存儲多對多配置。 否則,你的兩個表格設置是好的,但我仍然不會設置StudentIdQualification表中可以爲空,因爲沒有學生,資格是沒有什麼。一名學生擁有一個或多個資格證書,然後一個資格證書必須有一個學生,如果您反其道而行之。

這是由Microsoft Entity Framework生成的代碼。

學生

namespace DL.SO.StudentQualification.Data 
{ 
    using System; 
    using System.Collections.Generic; 

    public partial class Student 
    { 
     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 
     public Student() 
     { 
      this.Qualifications = new HashSet<Qualification>(); 
     } 

     public int Id { get; set; } 
     public string Name { get; set; } 
     public Nullable<int> Age { get; set; } 
     public Nullable<bool> Gender { get; set; } 
     public string City { get; set; } 

     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
     public virtual ICollection<Qualification> Qualifications { get; set; } 
    } 
} 

資格

namespace DL.SO.StudentQualification.Data 
{ 
    using System; 
    using System.Collections.Generic; 

    public partial class Qualification 
    { 
     public int Id { get; set; } 
     public int StudentId { get; set; } 
     public string QualificationName { get; set; } 
     public string Institute { get; set; } 
     public Nullable<System.DateTime> EffectiveDate { get; set; } 

     public virtual Student Student { get; set; } 
    } 
} 

這裏是控制器方法來獲取學生的代碼。

public JsonResult GetStudentInfo(int studentId) 
    { 
     using (var db = new AppDbContext()) 
     { 
      // Method syntax 
      var student = db.Students 
       .SingleOrDefault(x => x.Id == studentId); 

      // Query syntax 
      //var student = 
      // from s in db.Students 
      // where s.Id == studentId 
      // select s; 

      return Json(student, JsonRequestBehavior.AllowGet); 
     } 
    } 

你並不需要尋找一名學生,其學歷分開(否則爲什麼要使用EF),因爲EF的導航特性可以幫助你。我認爲這是你的錯誤來自哪裏。

如果你這樣做student.Qualifications,那麼你有一個該學生的資格列表。

其他建議:

  1. 不要直接返回數據庫模型回到頁面,即,它返回查看或恢復其作爲JSON對象,因爲你不希望暴露屬性,你不要不想暴露給公衆。使用ViewModel來定義您真正想要公開的屬性並將數據傳輸到視圖模型。改爲返回視圖模型。
  2. 您可能會考慮使用存儲庫模式並將DbContext注入存儲庫。那裏有很多材料。你可以谷歌和學習。
相關問題