C# 我应该何时处理数据上下文

C# 我应该何时处理数据上下文,c#,linq,linq-to-sql,C#,Linq,Linq To Sql,我目前正在为一个应用程序编写一个数据访问层。访问层广泛使用linq类来返回数据。目前,为了将数据反射回数据库,我添加了一个私有数据上下文成员和一个公共保存方法。代码如下所示: private DataContext myDb; public static MyClass GetMyClassById(int id) { DataContext db = new DataContext(); MyClass result = (from item in db.MyClasss

我目前正在为一个应用程序编写一个数据访问层。访问层广泛使用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();
}

这是一个严重的过度简化,但它给出了总体思路。有没有更好的方法来处理这种模式?我是否应该在每次访问db时都实例化一个新的数据上下文?

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

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


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

将您的datacontext视为一种资源。使用资源的规则是

“尽可能晚地获取资源 如果可能,请尽快释放它 “安全”


其实没什么大不了的。不久前,我向LINQ to SQL团队的Matt Warren询问了这方面的问题,以下是答案:

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

如果应用程序逻辑需要保持 当 预期将使用DataContext,或 你可以通过以下方式强制执行该合同: 呼叫Dispose。中的延迟加载程序 该实体仍将被引用 DataContext并将尝试使用它 如果任何代码试图导航 递延财产。这些尝试 将失败。Dispose还强制 要转储其缓存的DataContext 物化实体,使单个 缓存的实体不会意外损坏 使所有实体保持活动状态 通过数据上下文,这将 否则,会导致出现 内存泄漏

自动关闭的逻辑 DataContext连接可以是 被骗离开连接 打开DataContext依赖于 应用程序代码枚举所有 自到达后的查询结果 结果集的结尾将触发 要关闭的连接。如果 应用程序使用IEnumerable的 MoveNext方法而不是foreach方法 语句,您可以退出 枚举过早终止。如果你的 应用经验与问题 连接未关闭,您 怀疑自动关闭行为 不工作,您可以使用Dispose 模式作为一种变通方法


但基本上,在大多数情况下,你并不真的需要处理它们——这是出于设计。我个人更喜欢这样做,因为遵循“处理所有实现IDisposable的东西”的规则更容易而不是记住它的大量异常-但是如果忘记处理它,就不太可能泄漏资源。

我的目标是设置它,以便使用仅对象与数据库交互的人使用
Save()
方法。存储库模式就是这样做的吗?您是否有指向此处所指示例的链接?您可能想了解存储库模式。Walther先生在asp.net\learn\的mvc视频教程中的一个视频就是一个简单的例子。将其视为资源是一个好主意,但在某些情况下,您无法将其处理为延迟加载。在我看来,您可以不处理它而不必面对严厉的惩罚是非常有用的。我想知道这个答案是否适用于新的DbContext类@恐怕不知道。我不认为是这样。鉴于引用的文本,我实际上得出了一个结论,即你应该在处理完上下文后立即处理它,而不是说它“不太重要”。因为有两种选择:A)想知道一个程序员是否遇到了Matt Warren描述的两种昂贵的gotcha条件中的任何一种,或者B)只是有一个总括规则在完成后调用IDisposables上的dispose。我发现B让事情变得更容易,特别是在大型团队中