ASP.NET - SQL - 检索“包含”对象

时间:2012-11-15 02:24:40

标签: c# asp.net sql linq

所以我有2个表CommentsStudents。每个评论都有一个学生: Comment.StudentId

我正在使用POCO生成的类,当我像这样进行查询时,它似乎在Comment类中给了我整个Student对象:

var query =
    from comment in context.Comments
    where comment.StudentId == properId
    orderby comment.Created
    select comment;

所以我可以访问学生属性,如comment.Student.Name

但是,当我复制结果(query.ToList()以在方法外部使用时,它会给出一个错误,说明ObjectContext实例已被处理。

如何从对象中包含的对象中检索数据?

3 个答案:

答案 0 :(得分:2)

在.ToList()

之前添加.Include(“Student”)

答案 1 :(得分:1)

请记住,Linq使用IEnumerable,它会推迟执行查询,直到您尝试迭代结果(就像调用.ToList()一样)。如果你正如你所说的那样在方法之外调用.ToList(),那么你可能正在处理上下文,这意味着查询对象不再可行。

快速而肮脏的黑客是确保在处理上下文之前执行一次查询:

var query =
    (from comment in context.Comments
    where comment.StudentId == properId
    orderby comment.Created
    select comment).ToList();

答案 2 :(得分:1)

在退出包含dbcontext的方法之前,必须调用.ToList()。这将调用数据库并填写您的Comment类。否则,当您尝试在该方法之外“从对象中包含的对象中检索数据”并且尚未加载它们时,您将看到DbContext已被释放。这是因为EF试图为这些项目“加载”或“调用数据库”。当然,由于您现在位于包含上下文的方法之外,因此EF无法加载它们。你应该阅读EF的“延迟加载”功能,我认为这是默认打开的。

您可能想要创建一个只返回完全加载的Comment对象的方法。像这样:

public class YourDbAccessClass {
    public IEnumerable<Comment> GetCommentsByStudentId(int id) {
        using (YourContextClass context = new YourContextClass()) {
            // Eager load Student with the .Include() method.
            var query = from comment in context.Comments.Include("Student")
                        where comment.StudentId == id
                        orderby comment.Created
                        select comment;

            return query.ToList();
        }
    }
}

然后在你的主叫代码中:

protected void ...some method on your view or asp page {
    YourDbAccessClass db = new YourDbAccessClass();
    var comments = db.GetCommentsByStudentId(yourIdVariableHere);

    // Now you can loop through those items without dbcontext.
    // Response.Write is probably a bad example, but you probably get the gist here.
    foreach(var comment in comments) {
        Response.Write("<li>" + comment.Student.Name + "</li>");
    }
}