Когда записи из связанных таблиц загружаются с помощью LINQ2SQL
Допустим, у меня есть две таблицы:
- отчет
- Комментарий
И при условии, что у меня есть контекст базы данных:
var reports = db.Reports();
Как я могу убедиться, что все комментарии для каждого отчета также загружены?
На данный момент я хочу отключиться от базы данных, но все еще имею доступ к комментариям. (Например:)
reports[0].Comments[0].Subject
2 ответа
Я предполагаю, что между отчетами и комментариями существует 1-М ФК (1 отчет может иметь много комментариев)?
Одним из вариантов является использование метода DataLoadOptions.LoadWith - что-то вроде следующего:
var reports = db.Reports();
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Reports>(r => r.Comments); // Ask for Comments along with reports
reports.LoadOptions = dlo;
Теперь, каждый раз, когда вы выбираете отчет по этому контексту данных, комментарии будут извлекаться из БД вместе с ним.
Просто имейте в виду, что будут выбраны ВСЕ поля из комментариев - с помощью этого метода невозможно выбрать подмножество полей.
Другой вариант - указать, что вы хотите выбрать в запросе Linq, например:
var myReportsList = from report in db.Reports
select new { // Using anonymous type, but could use a custom class
Report = report,
Comment = report.Comment.Detail, // for example
Subject = report.Comment.Subject
};
Чтобы понять, когда запрос запускается и соединение с базой данных закрывается, вам нужно понять:
- Модель отложенного выполнения Linq и Linq To Sql (в основном, для Linq to SQL запрос выполняется только тогда, когда запрашиваются результаты, например, путем перебора коллекции или привязки к сетке)
- Разница между IQueryable и IEnumerable
Джон Скитс "C# в глубине" дает отличный обзор их, и я также слышал очень хорошие вещи о "Linq в действии" - плюс есть много постов в блоге об этих концепциях, которые делают темы более справедливыми, чем я могу здесь; о)
Имейте в виду, что если вы используете LoadOptions для определения многопрыжкового пути (отчеты, комментарии, анотерентность), третий и последующие прыжки загружаются (если они связаны между собой отношениями 1:n) с помощью кода, который очень неэффективен: они будут выполняться один запрос на одного родителя. Для отчетов-комментариев все в порядке, они будут получены в 2 запроса.