【问题标题】:When should I dispose of a data context我应该什么时候处理数据上下文
【发布时间】:2010-09-28 05:41:40
【问题描述】:

我目前正在为应用程序编写数据访问层。访问层广泛使用 linq 类来返回数据。目前,为了将数据反映回数据库,我添加了一个私有数据上下文成员和一个公共保存方法。代码如下所示:

private DataContext myDb;
public static MyClass GetMyClassById(int id)
{
    DataContext db = new DataContext();
    MyClass result = (from item in db.MyClasss
                      where item.id == id
                      select item).Single();
    result.myDb = db;
    return result;
}

public void Save()
{
    db.SubmitChanges();
}

这是一个粗略的简化,但它给出了一般的想法。有没有更好的方法来处理这种模式?每次我想访问数据库时,我是否应该实例化一个新的数据上下文?

【问题讨论】:

  • 您可能想了解存储库模式。在 asp.net\learn\ 的 mvc 视频教程中,Walther 先生的其中一个视频中有一个简单的示例

标签: c# linq linq-to-sql


【解决方案1】:

DataContext 非常轻量级,适用于您正在使用的工作单元应用程序。但是,我认为我不会将 DataContext 保留在我的对象中。如果您不打算使用设计器生成的代码来管理您的业务对象,您可能需要查看存储库模式。存储库模式将允许您使用与数据上下文分离的对象,然后在进行更新之前重新附加它们等。

就我个人而言,我能够在大部分情况下使用 DBML 设计器生成的代码,以及我的业务和验证逻辑的部分类实现。我还将设计器生成的数据上下文抽象化并从中继承,以允许我拦截直接添加到数据上下文中的存储过程和表值函数方法等内容,并在那里应用业务逻辑。

我一直在 ASP.NET MVC 中使用的一种模式是注入一个工厂类,该类根据工作单元的需要创建适当的数据上下文。使用工厂允许我通过(1)使用围绕现有数据上下文类的包装器相当容易地模拟数据上下文,以便它是可模拟的(模拟包装器,因为 DataContext 不容易模拟)和(2)创建假/模拟上下文和工厂来创造它们。能够从工厂随意制造它们,这样我就不必长时间保留它们。

【讨论】:

  • 我的目标是设置它,以便使用对象仅与数据库交互的人是Save() 方法。这就是存储库模式的作用吗?你有链接到你在这里的意思的一些例子吗?
【解决方案2】:

将您的数据上下文视为资源。并且使用资源的规则说

"获取资源最晚 可能的,尽快释放它 安全”

【讨论】:

  • 虽然将其视为资源是一个好主意,但在某些情况下,您不能将其用于延迟加载。 IMO,您可以在不处置的情况下离开它并且不会面临严厉的处罚,这是非常有用的。
【解决方案3】:

其实也没什么大不了的。不久前,我向 LINQ to SQL 团队的 Matt Warren 询问了这个问题,以下是回复:

我们实施的原因有几个 IDisposable:

如果应用程序逻辑需要保持 到一个实体上 预计将使用 DataContext 或 有效,您可以通过以下方式执行该合同 调用处置。延迟加载程序 该实体仍将引用 DataContext 并将尝试使用它 如果任何代码尝试导航 延迟属性。这些尝试 将失败。 Dispose 还强制 DataContext 转储其缓存 实体化实体,以便单个 缓存的实体不会意外 使所有实体保持活力 通过那个 DataContext,这将 否则会导致看起来像 内存泄漏。

自动关闭的逻辑 DataContext 连接可以是 被骗离开连接 打开。 DataContext 依赖于 枚举所有应用程序代码 自到达后的查询结果 结果集的结尾触发 连接关闭。如果 应用程序使用 IEnumerable 的 MoveNext 方法而不是 foreach C#或VB中的语句,可以退出 枚举过早。如果你的 应用程序遇到问题 连接没有关闭,你 怀疑自动关闭行为 不工作你可以使用 Dispose 模式作为一种解决方法。

但基本上,在大多数情况下,您真的需要处理它们 - 这是设计使然。无论如何,我个人更喜欢这样做,因为遵循“处理所有实现 IDisposable 的东西”的规则比记住它的大量异常更容易 - 但如果你 do 忘记处理它。

【讨论】:

  • 我想知道这个答案是否适用于新的 DbContext 类? msdn.microsoft.com/en-us/library/…
  • @tugberk:不知道,恐怕。我不认为它是。
  • 鉴于引用的文本,我实际上得出的结论是,您应该始终在完成后立即处理上下文,而不是“没关系”太多了”。因为有以下选择:A) 想知道编码人员是否偶然发现了 Matt Warren 描述的这两个昂贵的陷阱条件中的任何一个,或者 B) 只是有一个笼统的规则来调用 IDisposables 上的 dispose。我发现 B 让事情变得更容易,尤其是在大型团队中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-04
  • 2010-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多