c# – 为什么在DataContext上调用Dispose()之后可以枚举DbLinq查
更新 – 答案显然是Db
Linq没有正确实现Dispose(). D’哦!
以下是所有类型的误导 – 底线:DbLinq(尚未)等同于LinqToSql,正如我最初提出这个问题时所假设的那样.请谨慎使用! 我正在使用DbLinq的Repository Pattern.我的存储库对象实现了IDisposable,而Dispose()方法只做了一件事 – 在DataContext上调用Dispose().每当我使用存储库时,我将其包装在using块中,如下所示: public IEnumerable<Person> SelectPersons() { using (var repository = _repositorySource.GetPersonRepository()) { return repository.GetAll(); // returns DataContext.Person as an IQueryable<Person> } } 这个方法返回一个IEnumerable< Person>,所以如果我的理解是正确的,那么在Enumerable< Person>之前不会实际查询数据库.遍历(例如,通过将其转换为列表或数组或在foreach循环中使用它),如下例所示: var persons = gateway.SelectPersons(); // Dispose() is fired here var personViewModels = ( from b in persons select new PersonViewModel { Id = b.Id,Name = b.Name,Age = b.Age,OrdersCount = b.Order.Count() }).ToList(); // executes queries 在这个例子中,在设置person之后立即调用Dispose(),这是一个IEnumerable< Person>,这是它被调用的唯一时间. 那么,有三个问题: >这是如何工作的?在处理DataContext之后,处理后的DataContext如何仍然在数据库中查询结果? 解决方法
它不起作用.有些东西你没有向我们展示.我猜你的存储库类没有正确地/正确地处理DataContext,或者你在每个查询结束时都在执行写入ToList(),这完全否定了你通常得到的查询转换和延迟执行. 在测试应用程序中尝试以下代码,我保证会抛出ObjectDisposedException: // Bad code; do not use,will throw exception. IEnumerable<Person> people; using (var context = new TestDataContext()) { people = context.Person; } foreach (Person p in people) { Console.WriteLine(p.ID); } 这是最简单的可重复的情况,它总是会抛出.另一方面,如果您编写people = context.Person.ToList(),那么查询结果已经在使用块中枚举,我敢打赌在您的情况下发生了什么.
除此之外,它还设置了一个标志,表明DataContext已被处理,并在每个后续查询中进行检查,并使DataContext抛出一个ObjectDisposedException,其消息为Object name:’Dispose后访问DataContext’. 如果DataContext打开它并将其保持打开状态,它也会关闭连接.
有必要Dispose DataContext,因为必须Dispose所有其他IDisposable.如果未能处理DataContext,则可能会泄漏连接.如果从DataContext检索的任何实体保持活动状态,您也可能泄漏内存,因为上下文为其实现的工作单元模式维护内部标识缓存.但即使不是这种情况,也不关心Dispose方法在内部做什么.假设它做了一些重要的事情. IDisposable是一份合同,上面写着“清理可能不是自动的;你需要在完成后处理我.”如果您忘记Dispose,则无法保证对象是否有自己的终结器可以清理.实现可能会发生变化,这就是为什么依赖观察到的行为而不是明确的规范并不是一个好主意. 如果使用空Dispose方法处理IDisposable,最糟糕的事情就是浪费了几个CPU周期.如果您未能通过非平凡的实现来处置IDisposable,那么最糟糕的事情就是泄漏资源.这里的选择很明显;如果你看到IDisposable,不要忘记处理它. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |