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

C# ASP.NET-SQL-检索“包含的”对象,c#,asp.net,sql,linq,C#,Asp.net,Sql,Linq,所以我有两个表格,分别是评论和学生。每个评论都有一个学生: 评论,学生ID 我使用的是POCO生成的类,当我进行如下查询时,它似乎为我提供了注释类中的整个Student对象: var query = from comment in context.Comments where comment.StudentId == properId orderby comment.Created select comment; 因此我可以访问学生属性,如So comment.

所以我有两个表格,分别是评论和学生。每个评论都有一个学生: 评论,学生ID

我使用的是POCO生成的类,当我进行如下查询时,它似乎为我提供了注释类中的整个Student对象:

var query =
    from comment in context.Comments
    where comment.StudentId == properId
    orderby comment.Created
    select comment;
因此我可以访问学生属性,如So comment.student.Name

但是,当我将results query.ToList复制到方法外部使用时,会出现一个错误,表示已释放ObjectContext实例


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

add.IncludeStudent before.ToList

add.IncludeStudent before.ToList

请记住,Linq使用IEnumerable,这会延迟查询的执行,直到您尝试通过调用.ToList对结果进行迭代为止。如果您在所述方法之外调用.ToList,那么很可能您正在处理上下文,这意味着查询对象不再可行

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

var query =
    (from comment in context.Comments
    where comment.StudentId == properId
    orderby comment.Created
    select comment).ToList();
请记住,Linq使用IEnumerable,这会推迟查询的执行,直到您尝试通过调用.ToList对结果进行迭代为止。如果您在所述方法之外调用.ToList,那么很可能您正在处理上下文,这意味着查询对象不再可行

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

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

在退出包含dbcontext的方法之前,必须调用.ToList。这将调用数据库并填充注释类。否则,当您尝试从该方法之外的对象中包含的对象检索数据时,如果这些对象尚未加载,您将看到DbContext已被释放。这是因为EF正在尝试再次加载或调用这些项目的数据库。当然,由于您现在在包含上下文的方法之外,EF无法加载它们。您应该仔细阅读EF的延迟加载特性,我认为它在默认情况下是打开的

您可能需要创建一个只返回完全加载的注释对象的方法。大概是这样的:

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

在退出包含dbcontext的方法之前,必须调用.ToList。这将调用数据库并填充注释类。否则,当您尝试从该方法之外的对象中包含的对象检索数据时,如果这些对象尚未加载,您将看到DbContext已被释放。这是因为EF正在尝试再次加载或调用这些项目的数据库。当然,由于您现在在包含上下文的方法之外,EF无法加载它们。您应该仔细阅读EF的延迟加载特性,我认为它在默认情况下是打开的

您可能需要创建一个只返回完全加载的注释对象的方法。大概是这样的:

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

IORDeredQueryTable似乎没有上下文中的comment中的函数。Comments.IncludeStudentiOrderedQueryTable似乎没有上下文中的comment中的函数。Comments.IncludeStudent