更新 -答案是显然这DbLinq没有实现 Dispose() 正确。D'oh!


以下是所有的排序有误导性-的底线:DbLinq是没有(尚未)相当于LinqToSql,我假定当我最初来问这个问题。使用它以小心!

我使用的储存库模式与DbLinq.我的储存库的目的实施 IDisposable, , Dispose() 方法不会只有一件事--电话 Dispose()DataContext.只要我使用一个仓库我把它包装在一个 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

在这个例子中, Dispose() 被称为立即设定之后 persons, ,这是一个 IEnumerable<Person>, 这就是只有时它被称为。

因此,三个问题:

  1. 这怎么工作的?怎么可能一个布置 DataContext 仍在数据库中查询后的结果 DataContext 已经布置的?
  2. 这是什么 Dispose() 实际上做什么?
  3. 我听说这是没有必要(例如,请参阅 这个问题)处置 DataContext, 但我的印象是,它不是一个糟糕的想法。没有任何理由 要处理的一个DbLinq DataContext?
有帮助吗?

解决方案

1这怎么工作的?如何可以设置一个属性仍在数据库中查询结果后的属性已被置?

它的 不不 的工作。有些东西你们不是表示我们。我猜你的存储库类不处理的 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() 相反,然后查询结果已经列举的 内部using 方框,它我打赌是什么发生在你的情况。

2这是什么Dispose()实际上做什么?

除其他事项外,它将设置一个标志,指示 DataContext 布置的,这是检查每一个后续查询和原因的 DataContext 扔一个 ObjectDisposedException 有消息 Object name: 'DataContext accessed after Dispose.'.

它还关闭连接,如果 DataContext 打开它,并把它打开。

3我听说这是没有必要(例如,见这一问题),以处理的一个属性,但我的印象是,它不是一个糟糕的想法。没有任何理由不处理的一个LinqToSql属性?

它的 有必要 DisposeDataContext, ,因为它是必要的 Dispose 每一个其他的 IDisposable.你可能会泄露的连接,如果你不处理掉的 DataContext.你也可以泄漏的记忆,如果任何实体从 DataContext 被保持存活,由于该背景下维护一个内部的身份缓存单元的工作模式,它实现了。但是,即使没有这样的情况下, 这不是你的关心 什么样的 Dispose 方法并在内部。假设它确实一些重要的东西。

IDisposable 是一个 合同 说,"清理可能不是自动的;你需要处理我,当你完成。" 你有没有保障,是否对象都有其自身的终结,清除后如果你忘记 Dispose.实现受到改变,这就是为什么它不是一个好主意,依靠观察到的行为而不是明确的规格。

最糟糕的事情可以发生,如果你处理一个 IDisposable 有一个空的 Dispose 方法是,你浪费了几CPU周期。最糟糕的事情可以发生,如果你 失败 处理一个 IDisposable非平凡的执行情况 这是你泄露的资源。选择这里是显而易见的;如果你看到一个 IDisposable, ,不要忘记处理它。

其他提示

"人"是一个综合的收集、属性(仓库)只是需要做的.GetNew的呼吁。

从选择/等关键词的语法糖扩展的方法加入该系统。皇宫的名字空间。这些扩展的方法增加的综合功能使用的查询,不属性.事实上,你可以做所有这一切都没有使用LINQ2SQL在,通过编程方式创造一种类型证明。

如果你试图作出任何进一步的储存库(属性)电话使用这些目的,这时候,你将会收到一个错误。

该类型的收集将包含所有的记录,从你的储存库,这就是为什么你不需要属性做出的查询。

扩展方法: http://msdn.microsoft.com/en-us/library/bb383977.aspx

皇宫的扩展方法:http://msdn.microsoft.com/en-us/library/system.linq.enumerable_members.aspx

内心深处,你可能会看到一个方法中使用这样一:

http://msdn.microsoft.com/en-us/library/y6wy5a0f(v=VS。100).aspx

在执行命令时,相关的连接目的是关闭时的相关数据读取器目的是关闭的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top