我应该相信LinqDataSource能够正确清理吗?

时间:2011-08-28 00:41:26

标签: linq garbage-collection dispose linqdatasource

使用LinqDataSource的OnSelecting方法进行第一次尝试,以便我可以指定更复杂的查询,我写道:

protected void CategoriesDataSource_OnSelecting(object sender, LinqDataSourceSelectEventArgs e)
    {
        using (DataLayerDataContext db = new DataLayerDataContext())
        {
            e.Result = (from feed in db.Feeds
                        where feed.FeedName.StartsWith("Google")
                        select feed.MainCategory).Distinct();
        }
    }

问题当然是using子句将Dispose DataLayerDataContext。 “解决方案”是在没有它的情况下编写它,但我担心上下文不会及时处理,它会在垃圾收集运行之前保持一堆连接打开,依此类推。 / p>

我不是这个领域的专家,所以对这是一个真正的问题有什么评论,还是我担心一无所获?

1 个答案:

答案 0 :(得分:3)

啊,另一个人因延期装载的不幸副作用而烧伤......

protected void CategoriesDataSource_OnSelecting(object sender, LinqDataSourceSelectEventArgs e)
{
    using (DataLayerDataContext db = new DataLayerDataContext())
    {
        e.Result = (from feed in db.Feeds
                    where feed.FeedName.StartsWith("Google")
                    select feed.MainCategory).Distinct().ToList();
        //                                              ^^^^^^^^^
    }
}

这将强制DataLayerDataContext立即运行查询并创建一个不依赖于上下文或连接的内存列表。这样您就可以立即获得结果,并且可以随时处理上下文。

唯一的问题(根据史蒂文的评论)是延迟加载的导航属性;即使您强制查询计算,如果您尝试查询任何引用其他LINQ对象(或LINQ对象列表)的属性,它们将无法加载,除非指定了立即需要的属性在DataContext的{​​{3}}中。请参阅以下示例:

protected void CategoriesDataSource_OnSelecting(object sender, LinqDataSourceSelectEventArgs e)
{
    using (DataLayerDataContext db = new DataLayerDataContext())
    {
        DataLoadOptions loadOptions = new DataLoadOptions();
        loadOptions.LoadWith<Category>(c => c.SomeReference);
        loadOptions.LoadWith<Category>(c => c.SomeOtherReferences);

        db.LoadOptions = loadOptions;

        e.Result = (from feed in db.Feeds
                    where feed.FeedName.StartsWith("Google")
                    select feed.MainCategory).Distinct().ToList();
    }
}

一旦手动指定了这些关联,LINQ to SQL将在查询执行时急切地将它们加载到内存中,而不是让它们延迟加载(在DataContext之后使用属性时会导致异常地布置。)