简体   繁体   English

LINQ to SQL - >无法访问已处置的对象。对象名:'Dispose后访问的DataContext

[英]LINQ to SQL -> Cannot access a disposed object. Object name: 'DataContext accessed after Dispose

Let say I have 2 tables which is Student and School. 假设我有两张桌子,即学生和学校。 Within my Student table I have a fkSchoolId linking to a School record. 在我的学生表中,我有一个fkSchoolId链接到学校记录。 However, if I retrieve my record as below 但是,如果我检索我的记录如下

public static List<Student> GetByType(string connString, int type)
{
    using (mydb_DataContext db = new mydb_dbDataContext(connString))
    {
        return (from t1 in db.Students
                where t1.type = type
                select t1).ToList();
    }
}

I will have the list of Student objects where I can access it in a foreach loop. 我将有一个Student对象列表,我可以在foreach循环中访问它。 But when I do as below, I will get an error when retrieving the school name. 但是当我这样做时,我会在检索学校名称时收到错误。

foreach(Student student in DAL.StudentLogic.GetByType(5))
{
    string schoolName = student.School.Name;
}

System.ObjectDisposedException: 'Cannot access a disposed object. System.ObjectDisposedException:'无法访问已处置的对象。 Object name: 'DataContext accessed after Dispose.'.' 对象名:'Dispose后访问的DataContext。'。'

May I know how can I get the foreign information stored in the return object so that I can access them? 我是否可以知道如何将外部信息存储在返回对象中以便我可以访问它们? Or better way, if I can specify to load up just the school Name? 或者更好的方法,如果我可以指定只加载学校名称?

Updated: If I do as follow, it works, but not sure how much it will impact the performance. 更新:如果我这样做,它可以工作,但不确定它将对性能产生多大影响。 I will do a benchmark and update to this topic again next week. 我将在下周再次对该主题进行基准测试和更新。

public static List<Student> GetByType(string connString, int type)
{
    using (mydb_DataContext db = new mydb_dbDataContext(connString))
    {
        List<Student> students = (from t1 in db.Students where t1.type = type select t1).ToList();

        foreach(Student student in students)
        {
            student.School.Name = db.Schools.Where(q => q.SchoolId == student.fkSchoolId).FirstOrDefault().Name;
        }
    }
}

I'll be able to access to student.School.Name in my return object. 我将能够访问返回对象中的student.School.Name。

Set the DeferredLoadingEnabled property to false : DeferredLoadingEnabled属性设置为false

Gets or sets a value that indicates whether to delay-load one-to-many or one-to-one relationships. 获取或设置一个值,该值指示是否延迟加载一对多关系或一对一关系。

Therefor the related data will be retrieved when materializing the query and not retrieved in a later stage (after context was disposed) 因此,在实现查询时将检索相关数据,而不是在稍后阶段(在上下文处理之后)检索相关数据

public static List<Student> GetByType(string connString, int type)
{
    using (mydb_DataContext db = new mydb_dbDataContext(connString))
    {
        db.DeferredLoadingEnabled = false;
        return (from t1 in db.Students
                where t1.type = type
                select t1).ToList();
    }
}

However consider thinking (depends on overall design/ program requirements and load) of having the context kept open for the lifetime of the class this functions sits in (in seems like a DAL class). 然而,考虑思考(取决于整体设计/程序要求和负载)使该上下文在该类的生命周期中保持打开(这看起来像一个DAL类)。 Then implement the IDisposable interface and dispose the context in it. 然后实现IDisposable接口并在其中处理上下文。 (Remember that the Dispose must be called explicitly). (请记住,必须明确调用Dispose )。


If all you want is the school name and you are using C# 7.0 you can use the named tuples this way: 如果你想要的只是学校名称并且你使用的是C#7.0,你可以这样使用命名的元组

public static List<(Student Student, string SchoolName)> GetByType(string connString, int type)
{
    using (mydb_DataContext db = new mydb_dbDataContext(connString))
    {
        return (from t1 in db.Students
                join school in db.Schoold on t1.SchoolId equals school.Id
                where t1.type = type
                select (t1, school.Name)).ToList();
    }
}

If you get compilation error CS8137 then you need to install the Nuget package of System.ValueTuple 如果出现编译错误CS8137,则需要安装System.ValueTuple的Nuget包

With Linq2Sql you can use LoadWith , eg 使用Linq2Sql,您可以使用LoadWith ,例如

using (mydb_DataContext db = new mydb_dbDataContext(connString))
{
    DataLoadOptions op = new DataLoadOptions();
    op.LoadWith<Student>(o => o.School);

    db.LoadOptions = op;
    return (from t1 in db.Students
        where t1.type = type
        select t1).ToList();
}

The one downside is that this is retrieving all columns in the school table. 一个缺点是这是检索学校表中的所有列。

暂无
暂无

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

相关问题 无法访问已处置的对象。 对象名称:“在Dispose之后访问DataContext - Cannot access a disposed object. Object name: 'DataContext accessed after Dispose linq to sql无法访问已处置的对象。 返回一个新创建的对象 - linq to sql Cannot access a disposed object. Returning a new created object 无法访问已处置的对象:DataContext - Cannot access a disposed object : DataContext AutoMapper IValueResolver:无法访问已处理的对象。 对象名称:&#39;IServiceProvider&#39; - AutoMapper IValueResolver: Cannot access a disposed object. Object name: 'IServiceProvider' ObjectDisposedException:无法访问已处置的对象。 对象名称:“调度程序” - ObjectDisposedException: Cannot access a disposed object. Object name: 'Dispatcher' C#&#39;无法访问已处置的对象。 对象名称:“ SslStream”。 - C# 'Cannot access a disposed object. Object name: 'SslStream'.' HangFire“无法访问已处置的对象。对象名称:'SqlDelegatedTransaction'” - HangFire "Cannot access a disposed object. Object name: 'SqlDelegatedTransaction'" 无法访问已处置的对象。 对象名称:&#39;tlsxyz&#39; - Cannot access a disposed object. Object name: 'tlsxyz' 无法访问已处置的对象。 对象名称:“ NumericUpDown” - Cannot access a disposed object. Object name: 'NumericUpDown' Linq2Db 异步插入 - 无法访问已处置的 object。 ObjectDisposed_ObjectName_Name' - Linq2Db Async Insert - Cannot access a disposed object. ObjectDisposed_ObjectName_Name'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM