代码之家  ›  专栏  ›  技术社区  ›  devuxer

为什么在对DataContext调用Dispose()之后可以枚举DbLinq查询?

  •  7
  • devuxer  · 技术社区  · 16 年前

    更新 -答案显然是DbLinq没有实现 Dispose()


    下面是所有误导性的底线: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<人> ,这是它唯一一次被呼叫。

    所以,有三个问题:

    1. 数据上下文 仍然查询数据库的结果后 数据上下文 已处理?
    2. 是什么
    3. 我听说没有必要(例如,见 this question 数据上下文 数据上下文
    3 回复  |  直到 9 年前
        1
  •  3
  •   Aaronaught    16 年前

    1这是怎么工作的?在释放DataContext之后,disposed 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() 里面 这个 using 布洛克,我敢打赌你的案子就是这样。

    2 Dispose()实际上做什么?

    数据上下文 ObjectDisposedException异常 Object name: 'DataContext accessed after Dispose.'.

    如果 数据上下文 把它打开,然后让它开着。

    3我听说没有必要(例如,看到这个问题)处理DataContext,但我的印象是这不是一个坏主意。有什么理由不处理LinqToSql DataContext吗?

    Dispose 数据上下文 处置 每隔 IDisposable 数据上下文 . 如果从 数据上下文 保持活动状态,因为上下文为它实现的工作单元模式维护一个内部标识缓存。但即使这些都不是事实, 这不关你的事 怎么回事 方法在内部执行。假设它做了一些重要的事情。

    是一个 合同 也就是说,“清理可能不是自动的;你需要在完成后处理我。”你不能保证对象是否有自己的终结器,如果你忘了清理它,它会在你之后清理

    如果你处理一个 一个空的 处置 方法是浪费一些CPU周期。如果你 失败 可识别的 用一个 非平凡的实现 是你泄露了资源。这里的选择是显而易见的;如果你看到 ,别忘了处理。

        2
  •  0
  •   Sprague    16 年前

    “persons”是一个IEnumerable集合,DataContext(repository)只需要进行.GetNew调用。

    from/select/etc关键字是添加到System.Linq命名空间中的扩展方法的语法糖。这些扩展方法添加了您在查询中使用的IEnumerable功能,而不是DataContext。实际上,通过编程创建IEnumerable来演示,您完全可以不用使用LINQ2SQL来完成所有这些。

    如果您试图使用这些对象进行任何进一步的存储库(DataContext)调用,那么您将收到一个错误。

    IEnumerable集合将包含存储库中的所有记录,这就是为什么不需要DataContext进行查询的原因。

    http://msdn.microsoft.com/en-us/library/bb383977.aspx

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

        3
  •  0
  •   Raj Kaimal    16 年前

    在API的深处,您可能会看到一个使用如下API的方法:

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

    执行命令时,关联的连接对象在关联的DataReader对象关闭时关闭。

    推荐文章