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

发布于 2024-12-02 00:44:51 字数 621 浏览 1 评论 0原文

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

我不是这方面的专家,所以对于这是否是一个真正的问题有什么评论,还是我的担心是多余的?

Taking my first stab as using the OnSelecting method of LinqDataSource so that I can specify a more complex query, I wrote this:

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

The problem, of course, is that the using clause will Dispose the DataLayerDataContext. The 'solution' is to write it without it, but I'm afraid then that the context won't be disposed of in a timely fashion, that it will leave a bunch of connections open until garbage collection runs, and so on.

I'm no expert in this area, so any comments on whether this is a real problem, or am I worried for naught?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

啊,另一个人被延迟加载的不幸副作用所困扰...

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 对象列表)的任何属性,它们也将无法加载除非您指定立即需要哪些属性在 DataLoadOptions数据上下文。请参阅下面的示例:

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 被释放。)

Ah, another person burned by the unfortunate side effects of deferred loading...

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

This will force the DataLayerDataContext to immediately run the query and create an in-memory list that's not dependent on the context or connection. That way you get your results immediately and you can dispose the context whenever you like.

The only problem (per Steven's comment) is the lazy-loaded navigation properties; even if you force the query to evaluate, if you try to query any properties that are references to other LINQ objects (or lists of LINQ objects) they will fail to load unless you specify what properties are immediately required in the DataLoadOptions of the DataContext. See the below for an example:

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

Once you manually specify these associations, LINQ to SQL will eagerly load them into memory when the query executes, instead of leaving them to deferred loading (which will cause an exception when the properties are used after the DataContext is disposed.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文