Ах, еще один человек сгорел от неблагоприятных побочных эффектов отложенной загрузки ...
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
. )