更新 - 答案显然是DbLinq没有Dispose()正确实施.D'哦!
以下是所有类型的误导 - 底线:DbLinq(尚未)等同于LinqToSql,就像我最初问这个问题时所假设的那样.请谨慎使用!
我正在使用DbLinq的Repository Pattern.我的资源库对象实施IDisposable和Dispose()方法不唯一-电话Dispose()上DataContext.每当我使用存储库时,我将其包装在一个using块中,如下所示:
public IEnumerable<Person> SelectPersons()
{
using (var repository = _repositorySource.GetPersonRepository())
{
return repository.GetAll(); // returns DataContext.Person as an IQueryable<Person>
}
}
Run Code Online (Sandbox Code Playgroud)
这个方法返回一个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
Run Code Online (Sandbox Code Playgroud)
在这个例子中,Dispose()在设置之后立即调用persons,这是一个IEnumerable<Person>,并且这是它被调用的唯一时间.
那么,三个问题:
DataContext后,DataContext处理后如何处理结果仍然可以查询数据库?Dispose()真正做到?DataContext,但我的印象是,这不是一个坏主意.有没有理由不处理DbLinq DataContext?1 这是如何运作的?已处置的 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);
}
Run Code Online (Sandbox Code Playgroud)
这是最简单的可重现情况,它总是会抛出异常。另一方面,如果您people = context.Person.ToList()改为编写,那么查询结果已经在块内using枚举,我敢打赌这就是您的情况所发生的情况。
2 Dispose() 实际上做了什么?
除其他外,它设置一个标志,指示DataContext已处理,在每个后续查询中都会检查该标志,并导致DataContext抛出ObjectDisposedException带有消息的Object name: 'DataContext accessed after Dispose.'.
如果连接打开并保持打开状态,它也会关闭连接DataContext。
3 我听说没有必要(例如,参见这个问题)处置 DataContext,但我的印象是这不是一个坏主意。是否有任何理由不处置 LinqToSql DataContext?
这对他们来说是必要的,正如对其他人来说也是必要的一样。如果您未能处置. 如果从 检索到的任何实体保持活动状态,您也可能会泄漏内存,因为上下文为其实现的工作单元模式维护内部身份缓存。但即使情况并非如此,您也不关心该方法内部执行什么操作。假设它做了一些重要的事情。DisposeDataContextDisposeIDisposableDataContextDataContextDispose
IDisposable是一份合同,上面写着:“清理可能不会自动进行;完成后你需要处理掉我。” 您无法保证该对象是否有自己的终结器,如果您忘记了,该终结器会在您之后进行清理Dispose。实现可能会发生变化,这就是为什么依赖观察到的行为而不是明确的规范并不是一个好主意。
IDisposable如果你用空方法处理一个可能发生的最糟糕的事情Dispose是你浪费了一些CPU周期。如果您未能IDisposable通过一个不平凡的实现来处理一个可能发生的最糟糕的事情,那就是您泄漏了资源。这里的选择是显而易见的;如果您看到IDisposable,请不要忘记将其丢弃。
| 归档时间: |
|
| 查看次数: |
650 次 |
| 最近记录: |