【问题标题】:LINQ functions and DataContext disposal, deferred executionLINQ 函数和 DataContext 处理,延迟执行
【发布时间】:2012-02-04 14:04:56
【问题描述】:

所以我需要一些建议和见解。提前感谢您的想法。

我开发了从 LINQ 实体返回单个记录的静态函数。像这样:

FooRecord GetRecord(Guid id)
{
   using(var dc = new FooDataContext())
       return dc.FooRecords.Where(a => a.Id == id).First();
}

这会引发异常,因为 DataContext 已被释放,这会产生延迟执行的问题。这有效:

FooRecord GetRecord(Guid id)
{
       var dc = new FooDataContext();
       return dc.FooRecords.Where(a => a.Id == id).First();
}

我很担心。处理 DataContext 的速度有多快?显然,如果我立即抓住记录,这不会造成问题。但是,假设我需要通过关联来获取记录:

var record = Data.FooRecord.GetRecord(id);
//Do a bunch of stuff...
//Now we grab the related record from another entity
var barRecord = record.BarRecord

此时 DataContext 是否存在消失的风险?有什么建议吗?

【问题讨论】:

    标签: sql linq idisposable deferred-execution


    【解决方案1】:

    由于此处讨论的原因,您基本上不需要 Dispose() 您的 DataContext:

    When should I dispose of a data context

    http://csharpindepth.com/ViewNote.aspx?NoteID=89

    在一个类型上实现 IDisposable 的主要原因是为了释放所有非托管资源。 DataContext 分配的唯一非托管资源是底层数据库连接,但 DataContext 已经负责根据需要打开和关闭连接。

    您要避免的主要事情是返回一个 IEnumerable 集合,然后从不枚举它,因为这将导致连接无限期地保持打开状态。但是,由于您只返回一个对象,因此您不必担心这一点。

    还要注意,如果访问返回对象上的任何关系属性,可能会导致连接暂时重新打开,以便可以延迟加载该属性。您可以通过将 DataLoadOptions.LoadWith() 与 DataContext 一起使用来预先加载您打算访问的任何属性来避免这种情况。见http://msdn.microsoft.com/en-us/library/system.data.linq.dataloadoptions.aspx

    至于问题的最后一部分,如果返回的实体包含可以延迟加载的属性,那么它们将包含内部引用来支持将其保存在内存中的 DataContext。一旦不再引用这些实体,DataContext 就会像任何其他对象一样被垃圾回收。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-12
      • 1970-01-01
      • 1970-01-01
      • 2013-06-19
      • 2014-09-15
      • 2011-11-11
      • 2011-04-02
      相关资源
      最近更新 更多