Должен ли я доверять LinqDataSource для правильной очистки? - PullRequest
2 голосов
/ 28 августа 2011

Принимая мой первый удар за использование метода OnSelecting LinqDataSource, чтобы я мог указать более сложный запрос, я написал следующее:

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.«Решение» состоит в том, чтобы написать его без него, но я боюсь, что контекст не будет своевременно удален, что он оставит открытыми несколько соединений, пока не будет запущена сборка мусора и т. Д.

Я не эксперт в этой области, поэтому есть какие-либо комментарии по поводу того, является ли это реальной проблемой, или я беспокоюсь за ничто?

1 Ответ

3 голосов
/ 28 августа 2011

Ах, еще один человек сгорел от неблагоприятных побочных эффектов отложенной загрузки ...

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 из DataContext. Смотрите пример ниже:

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. )

...