我正在为应用程序编写数据访问层。访问层广泛使用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();
}
这是一个粗略的过度简化,但它给出了一般的想法。有没有更好的方法来处理这种模式?每次我想访问数据库时,我是否应该实例化一个新的数据上下文?
答案 0 :(得分:66)
实际上并不重要。我刚才向LINQ to SQL团队的Matt Warren询问了这个问题,以下是回复:
我们实施的原因有几个 IDisposable的:
如果应用程序逻辑需要保持 到了一个超越的实体 期望使用DataContext或 有效的,您可以执行该合同 调用Dispose。延期装载机 该实体仍将引用 DataContext并将尝试使用它 如果任何代码试图导航 延期财产。这些尝试 将失败。处置也迫使 DataContext转储其缓存 物化实体使单一 缓存实体不会意外 让所有实体保持活力 通过那个DataContext,它会 否则会导致看起来像是一个 记忆泄漏。
自动关闭的逻辑 DataContext连接可以 欺骗离开连接 打开。 DataContext依赖于 应用程序代码枚举所有 到达后的查询结果 结果集的结尾触发了 连接关闭。如果 应用程序使用IEnumerable MoveNext方法而不是foreach 在C#或VB中声明,你可以退出 过早的枚举。如果你的 应用程序遇到的问题 连接没有关闭和你 怀疑自动关闭行为 不工作你可以使用Dispose 模式作为一种解决方法。
但基本上你不会真的需要在大多数情况下处理它们 - 这是设计的。我个人更喜欢这样做,因为它更容易遵循“处理实现IDisposable的所有内容”的规则,而不是记住一堆例外情况 - 但是如果你那么你不可能泄漏资源/ em>忘记处理它。
答案 1 :(得分:16)
将您的datacontext视为资源。使用资源的规则说
“最迟获得资源 可能的,尽快释放它 安全“
答案 2 :(得分:5)
DataContext非常轻量级,适用于工作单元应用程序。但是,我不认为我会将DataContext保留在我的对象中。如果您不打算使用设计器生成的代码来管理业务对象,则可能需要查看存储库模式。存储库模式将允许您处理与数据上下文分离的对象,然后在进行更新之前重新附加它们等。
就个人而言,我能够在大多数情况下使用DBML设计器生成的代码,并为我的业务和验证逻辑提供部分类实现。我还将设计器生成的数据上下文抽象并从中继承,以允许我拦截直接添加到数据上下文并在那里应用业务逻辑的存储过程和表值函数方法之类的东西。
我在ASP.NET MVC中使用的模式是注入一个工厂类,根据工作单元的需要创建适当的数据上下文。使用工厂允许我通过以下方式合理地模拟数据上下文:(1)使用现有数据上下文类的包装器使其可模拟(模拟包装器,因为DataContext不容易模拟)和(2)创建假/模拟上下文和工厂来创造它们。能够从工厂随意创建它们使得我不必长时间保持它们。