C# 使用实体框架的ASP.NET web API中的子集合为空

C# 使用实体框架的ASP.NET web API中的子集合为空,c#,asp.net,entity-framework,asp.net-web-api2,C#,Asp.net,Entity Framework,Asp.net Web Api2,我正在尝试创建一个ASP.NET web服务,该服务使用实体框架公开学生和课程的列表。每门课程由多名学生组成: public class Student { public int Id { get; set; } public string Name { get; set; } } public class Course { public int Id { get; set; } public string Title { get; set; } pub

我正在尝试创建一个ASP.NET web服务,该服务使用实体框架公开学生和课程的列表。每门课程由多名学生组成:

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Course
{
    public int Id { get; set; }
    public string Title { get; set; }
    public ICollection<Student> Students { get; set; }
}
但是,当我使用web服务获取课程列表时,它返回JSON,其中学生设置为null:

[{"Id":1,"Title":"course1","Students":null},
 {"Id":2,"Title":"course2","Students":null},
 {"Id":3,"Title":"course3","Students":null}]
如何让web服务包含分配给每门课程的学生列表?提前谢谢


更新

Slauma将
GetCourses
更改为

public IEnumerable<Course> GetCourses()
{
    return db.Courses.Include(c => c.Students).AsEnumerable();
}
public IEnumerable GetCourses()
{
返回db.Courses.Include(c=>c.Students.AsEnumerable();
}
部分工作。martin_costello的第二个解决方案也有类似的效果。我需要做的另一件事是修改我的学生课堂,以明确指出多对多关系:

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<Course> CoursesAttending { get; set; }
}

public class Course
{
    public int Id { get; set; }
    public string Title { get; set; }
    public ICollection<Student> Students { get; set; }
}
公共班级学生
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共ICollection课程开始{get;set;}
}
公共课
{
公共int Id{get;set;}
公共字符串标题{get;set;}
公共ICollection学生{get;set;}
}
如何让web服务包含学生名单 分配给每门课程的

通过使用
包含
,您可以包含

public IEnumerable<Course> GetCourses()
{
    return db.Courses.Include(c => c.Students).AsEnumerable();
}
public IEnumerable GetCourses()
{
返回db.Courses.Include(c=>c.Students.AsEnumerable();
}
如何让web服务包含学生名单 分配给每门课程的

通过使用
包含
,您可以包含

public IEnumerable<Course> GetCourses()
{
    return db.Courses.Include(c => c.Students).AsEnumerable();
}
public IEnumerable GetCourses()
{
返回db.Courses.Include(c=>c.Students.AsEnumerable();
}

我认为用于延迟加载的EntityFramework功能可能不起作用,因为您的集合属性不是虚拟的。此外,您应该调用
ToList()
而不是
AsEnumerable()
,以便查询具体化数据库中的对象,并在方法返回之前执行查询

否则,可能会释放数据库上下文,这意味着该上下文(和数据库连接)不再存在,无法查找延迟加载以初始化Students集合

AsEnumerable()
调用实际上是一个no-op,它创建一个查询计划,以便在以后实际需要结果时(例如在
foreach
循环中)执行操作。
ICollection
已经是一个
IEnumerable
,因此无论如何都不需要强制转换

问题是您实际上没有在
GetCourses()
方法中执行查询

尝试将代码更改为:

// GET api/Course
public IEnumerable<Course> GetCourses()
{
    return db.Courses.ToList();
}

我认为用于延迟加载的EntityFramework功能可能不起作用,因为您的集合属性不是虚拟的。此外,您应该调用
ToList()
而不是
AsEnumerable()
,以便查询具体化数据库中的对象,并在方法返回之前执行查询

否则,可能会释放数据库上下文,这意味着该上下文(和数据库连接)不再存在,无法查找延迟加载以初始化Students集合

AsEnumerable()
调用实际上是一个no-op,它创建一个查询计划,以便在以后实际需要结果时(例如在
foreach
循环中)执行操作。
ICollection
已经是一个
IEnumerable
,因此无论如何都不需要强制转换

问题是您实际上没有在
GetCourses()
方法中执行查询

尝试将代码更改为:

// GET api/Course
public IEnumerable<Course> GetCourses()
{
    return db.Courses.ToList();
}

我也遇到了同样的问题,通过向模型属性添加
virtual
modifier解决了这个问题

public virtual List<Service> Services { get; set; } 
公共虚拟列表服务{get;set;}

我也遇到了同样的问题,通过向模型属性添加
虚拟
修改器解决了这个问题

public virtual List<Service> Services { get; set; } 
公共虚拟列表服务{get;set;}

我也有同样的问题,通过这种方式解决了。 在WebApiCongif.cs文件中添加以下代码:

C#
var json=config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling=Newtonsoft.json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);

我也有同样的问题,通过这种方式解决了。 在WebApiCongif.cs文件中添加以下代码:

C#
var json=config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling=Newtonsoft.json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);

您的edmx在这两个实体之间有关系吗Saravanan-我没有使用我知道的edmx文件。我只是使用代码优先开发。您的edmx在这两个实体之间有关系吗Saravanan-我没有使用我所知道的edmx文件。我只是使用代码优先开发。