简体   繁体   English

使用实体框架获取数据以便可以在对象之间导航的正确方法是什么?

[英]What's the proper way to get data using Entity Framework so you can navigate through objects?

I have a .Net 4.5 MVC 5 database first project that I'm playing around with. 我有一个正在玩的.Net 4.5 MVC 5数据库第一个项目。 There's a data access layer (Entity Framework 6), a business logic layer and the MVC layer. 有数据访问层(实体框架6),业务逻辑层和MVC层。

If I have an object with relationships in the data layer: 如果我在数据层中有一个具有关系的对象:

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

And in my business logic layer I have a method that gets courses: 在我的业务逻辑层中,我有一种获取课程的方法:

namespace BusinessLogic
{
    public static IEnumerable<Course> GetCourses()
    {
        using (var db = new MyEntities())
        {
            return db.Courses.Include("Lectures").Include("Lectures.Students").Include("Tutors").ToList();
        }
    }
}

And I get the data using my controller like this: 然后使用我的控制器获取数据,如下所示:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var courses = BusinessLogic.GetCourses();
        return View(courses);
    }
}

Why is it, when I query my data in the Razor view like this: 为什么这样,当我在Razor视图中查询数据时,如下所示:

var numLectures = courses.Lectures.Count;
var numStudents = courses.Lectures.Students.Count;
var tutorName = courses.Tutors.LastOrDefault().Name;

I get the application error System.ObjectDisposedException: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection . 我收到应用程序错误System.ObjectDisposedException:ObjectContext实例已被处置,不能再用于需要连接的操作

I know the connection is disposed after the using statement has finished and that .ToList() will let me navigate the courses object, but how do I navigate the objects inside each course (ie lectures, students, tutors etc.)? 我知道在using语句完成后会断开连接,并且.ToList()将使我可以浏览课程对象,但是如何浏览每门课程中的对象(即讲座,学生,导师等)?

Your navigation properties need to be declared as virtual : 您的导航属性需要声明为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; }
    }
    ...
}

When these lazy loadable properties are not marked as virtual , the EF dynamic proxies cannot override them and you will never be able to navigate from one entity to a (set of) another. 当这些可延迟加载的属性未标记为virtual ,EF动态代理将无法覆盖它们,并且您将永远无法从一个实体导航到另一个实体。

Another bit of advice: use the strongly-typed .Include when eager loading: 另一点建议:急于加载时,请使用强类型的.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();
        }
    }
}

I think the problem is because one (or more than one) property that you are calling in your View is (are) not included in your query. 我认为问题是因为查询中不包含您在View中调用的一个(或多个)属性。 Make sure you are including all the navigation properties you need in the view. 确保在视图中包含所需的所有导航属性。 Try with this query: 尝试使用以下查询:

  using (var db = new MyEntities())
  {
    return db.Courses.db.Courses.Include(c=>c.Lectures.Select(l=>l.Students)).Include(c=>c.Tutors‌​).ToList()
  }

If you need to add another relative property that you use in your View, then add another Include call for that property. 如果您需要添加在View中使用的另一个相对属性,请为该属性添加另一个Include调用。

Another thing, when you need to eager load two levels (like Lectures.Students ), you don't need to add a Include call for each level, with the call that you do for the second level is enough to include both. 另一件事,当您需要加载两个级别(例如Lectures.Students )时,不需要为每个级别添加一个Include调用,而您对第二个级别所做的调用就足以包含这两个级别。 Could be this way: 可能是这样的:

.Include("Lectures.Students") // as you did it

Or: 要么:

.Include(c=>c.Lectures.Select(l=>l.Students))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在Entity Framework中删除实体的正确方法是什么? - What's the proper way to delete entities in Entity Framework? 使用.NET 4实体框架删除引用的正确方法是什么? - What is the proper way to remove a reference using the .NET 4 Entity Framework? 在文件的两个带标签的行之间获取所有内容以便可以反序列化的最佳方法是什么? - What's the best way to get all the content in between two tagged lines of a file so that you can deserialize it? 实体框架排序导航对象 - Entity Framework Ordering Navigate Objects 使用导航对象的实体框架查询 - Entity Framework Querying with Navigate Objects 在Entity Framework Core中编写实体POCO类的正确方法是什么? - What is a proper way of writing entity POCO classes in Entity Framework Core? 在Entity Framework中创建递归实体的正确方法是什么? - What is the proper way to create a recursive entity in the Entity Framework? 使用实体框架无法获取数据 - can't get data using entity framework 将WCF服务中使用的Entity Framework连接字符串包含到自托管控制台应用程序中的正确方法是什么? - What's the proper way to include Entity Framework connection string used in WCF service into a self hosting console application? 使用Entity Framework 6检索数据的正确有效方法是什么 - What is the right and efficient way to retrieve data using Entity Framework 6
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM