序列化对象+ ASP.net mvc5 +实体框架

时间:2017-10-05 17:25:20

标签: c# asp.net asp.net-mvc entity-framework asp.net-mvc-4

我正在使用ASP.Net MVC 5,使用SQL Server实体框架开发测试应用程序。

在我的场景中,数据库中有2个表。 StudentQualification。 一名学生具有一项或多项资格。

我需要通过提供studentID从数据库中获取studentQualification(导航属性)的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模型类如下

    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; }
}

通过使用实体数据模型生成了上面的Model类。 我遵循数据库第一方法..

提前致谢。

1 个答案:

答案 0 :(得分:1)

夫妻俩:

  1. 我使用可空位作为Student类的性别类型,而不是byte
  2. 你说一个学生有一个或多个资格,但你没有提到同一个资格可以在不同的学生之间分享。如果,那么您需要第三个表StudentQualification来存储多对多配置。 否则,你的两个表设置没问题,但我仍然不会将StudentId表中的Qualification设置为可空,因为没有学生就没有资格。一个学生有一个或多个资格,然后一个资格必须有一个学生,如果你反过来考虑它。
  3. 这是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; }
        }
    }
    

    以下是获取学生的Controller方法的代码。

        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注入存储库。那里有大量的材料。你可以谷歌和学习。
相关问题