2

将我的第一个刺作为使用 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。“解决方案”是在没有它的情况下编写它,但我担心上下文不会被及时处理,它会留下一堆连接打开,直到垃圾收集运行,等等。

我不是这方面的专家,所以对这是否是一个真正的问题有任何评论,还是我担心白费?

4

1 回答 1

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立即运行查询并创建一个不依赖于上下文或连接的内存列表。这样您就可以立即获得结果,并且可以随时处理上下文。

唯一的问题(根据 Steven 的评论)是延迟加载的导航属性;即使您强制查询评估,如果您尝试查询引用其他 LINQ 对象(或 LINQ 对象列表)的任何属性,除非DataLoadOptionsDataContext. 请参阅下面的示例:

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();
    }
}

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

于 2011-08-28T01:52:22.447 回答