[英]What's the proper way to get data using Entity Framework so you can navigate through objects?
我有一个正在玩的.Net 4.5 MVC 5数据库第一个项目。 有数据访问层(实体框架6),业务逻辑层和MVC层。
如果我在数据层中有一个具有关系的对象:
namespace DataAccess
{
public class Course
{
public int CourseID { get; set; }
public string Title { get; set; }
public ICollection<Lecture> Lectures { get; set; }
public ICollection<Tutor> Tutors { get; set; }
}
public class Lecture
{
public int LectureID { get; set; }
public string Title { get; set; }
public DateTime Date { get; set; }
public ICollection<Student> Students { get; set; }
}
public class Tutor
{
public int TutorID { get; set; }
public string Name { get; set; }
}
public class Student
{
public int StudentID { get; set; }
public string Name { get; set; }
}
}
在我的业务逻辑层中,我有一种获取课程的方法:
namespace BusinessLogic
{
public static IEnumerable<Course> GetCourses()
{
using (var db = new MyEntities())
{
return db.Courses.Include("Lectures").Include("Lectures.Students").Include("Tutors").ToList();
}
}
}
然后使用我的控制器获取数据,如下所示:
public class HomeController : Controller
{
public ActionResult Index()
{
var courses = BusinessLogic.GetCourses();
return View(courses);
}
}
为什么这样,当我在Razor视图中查询数据时,如下所示:
var numLectures = courses.Lectures.Count;
var numStudents = courses.Lectures.Students.Count;
var tutorName = courses.Tutors.LastOrDefault().Name;
我收到应用程序错误System.ObjectDisposedException:ObjectContext实例已被处置,不能再用于需要连接的操作 。
我知道在using语句完成后会断开连接,并且.ToList()将使我可以浏览课程对象,但是如何浏览每门课程中的对象(即讲座,学生,导师等)?
您的导航属性需要声明为virtual
:
namespace DataAccess
{
public class Course
{
public int CourseID { get; set; }
public string Title { get; set; }
public virtual ICollection<Lecture> Lectures { get; set; }
public virtual ICollection<Tutor> Tutors { get; set; }
}
public class Lecture
{
public int LectureID { get; set; }
public string Title { get; set; }
public DateTime Date { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
...
}
当这些可延迟加载的属性未标记为virtual
,EF动态代理将无法覆盖它们,并且您将永远无法从一个实体导航到另一个实体。
另一点建议:急于加载时,请使用强类型的.Include
:
namespace BusinessLogic
{
public static IEnumerable<Course> GetCourses()
{
using (var db = new MyEntities())
{
return db.Courses
.Include(x => x.Lectures.Select(y => y.Students))
.Include(x => x.Tutors)
.ToList();
}
}
}
我认为问题是因为查询中不包含您在View中调用的一个(或多个)属性。 确保在视图中包含所需的所有导航属性。 尝试使用以下查询:
using (var db = new MyEntities())
{
return db.Courses.db.Courses.Include(c=>c.Lectures.Select(l=>l.Students)).Include(c=>c.Tutors).ToList()
}
如果您需要添加在View中使用的另一个相对属性,请为该属性添加另一个Include
调用。
另一件事,当您需要加载两个级别(例如Lectures.Students
)时,不需要为每个级别添加一个Include
调用,而您对第二个级别所做的调用就足以包含这两个级别。 可能是这样的:
.Include("Lectures.Students") // as you did it
要么:
.Include(c=>c.Lectures.Select(l=>l.Students))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.