[英]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.