DataContext的生命周期,LinqToSql

4

我在互联网上找到了一篇文章,介绍了如何实现仓储模式。实现方式与这里类似:

class ProductRepository : IProductRepository
{

    var context;
    public ProductRepository() {
        this.context = new MyDataBaseDataContext(); 
    }
    // the rest of methods
}

但我不确定这是否正确,上下文发生了什么?垃圾回收器会处理此对象吗?还是最好使用using (...) { }语句创建上下文?


1
这对我来说似乎是完全有效的。如果您的存储库类拥有可处理的数据上下文,则它本身也应该是可处理的(符合任何具有可处理成员的类都应实现IDisposable指南)。 - MattDavey
3个回答

2

Repository 不应该打开数据上下文,DataContext 必须被传递给它 - 因为它不应该拥有它。 假设你有一个需要在事务中进行且涉及多个仓库的操作,你会怎么做?

你需要使用 UnitOfWork 模式

在这个模式中,将一个封装了 DataContextUoW 传递给一个仓库。

实际上,业务层的 ProductManager 创建一个 Unit Of Work


为什么必须让一个仓库不拥有数据上下文?我同意UOW是一个很好的设计,但你的回答措辞暗示着这是一条明确的规则,其实还有许多同样有效的方法... - MattDavey
因为它可能不知道 DataContext 的生命周期应该是什么样的。例如,在 Web 场景中,数据上下文是每个请求创建一次,这不是存储库必须具备的知识。 - Aliostad
除非数据上下文的生命周期应该与存储库本身的生命周期相同,否则让存储库负责管理其自身依赖项的生命周期是完全合理的。在Web场景中,并不是每个请求都会创建一个数据上下文,数据上下文可以根据您的需要长时间或短时间存在,它与Web请求没有任何关联。 - MattDavey

1
简单来说,这个问题的答案是仓库应该确保自己处理数据上下文,而不是让它由.NET运行时自动处理。这可以通过遵循标准的.NET处理模式来实现...
class ProductRepository : IProductRepository, IDisposable
{
    var context;

    public ProductRepository() {
        this.context = new MyDataBaseDataContext(); 
    }

    // the rest of methods

    public void Dispose()
    {
        if (context != null)
        {
            context.Dispose();
            context = null;
        }
    }
}

0
我想这取决于您是否需要在存储库操作之间进行事务处理以及您对跟踪更改的需求。数据DataContext可以非常有帮助,因为它可以让您检索一堆对象,将它们修改应用程序,然后只需在任何时候调用SubmitChanges /RollbackChanges即可。但是,如果您不在存储库中公开此功能,则最好在每个存储库方法中“使用”一个实例,因为这将保留内存使用和资源以跟踪更改。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接