Я уже некоторое время без проблем использую методы расширения .Skip () и .Take () с LINQ To SQL, но во всех ситуациях, в которых я их использовал, всегда было для одной таблицы - такие как:
database.Users.Select(c => c).Skip(10).Take(10);
Моя проблема заключается в том, что я теперь проецирую набор результатов из нескольких таблиц и хочу просмотреть весь набор (и при этом получить выгоду от разбивки на страницы в БД).
Моя модель сущности выглядит так:
Кампания [имеет много] групп, группа [имеет много] контактов
это моделируется через отношения в базе данных, такие как
Кампания -> CampaignToGroupMapping -> Группа -> GroupToContactMapping -> Контакт
Мне нужно сгенерировать структуру данных, содержащую подробности кампании, а также список каждого контакта, связанного с кампанией через CampaignToGroupMapping, т.е.
Campaign
CampaignName
CampaignFrom
CampaignDate
Recipients
Recipient 1
Recipient 2
Recipient n...
Я пытался написать запрос LINQ, используя .SelectMany для проецирования набора контактов из каждой группы в один линейный набор данных, в надежде, что смогу .Skip () .Take () из этого.
Моя попытка была:
var schedule = (from c in database.Campaigns
where c.ID == highestPriority.CampaignID
select new PieceOfCampaignSchedule
{
ID = c.ID,
UserID = c.UserID,
Name = c.Name,
Recipients = c.CampaignGroupsMappings.SelectMany(d => d.ContactGroup.ContactGroupMappings.Select(e => new ContactData() { /*Contact Data*/ }).Skip(c.TotalSent).Take(totalRequired)).ToList()
}).SingleOrDefault();
Проблема в том, что подкачка (в отношении Skip () и Take ()) происходит для каждой группы, а не для всего набора данных.
Это означает, что если я использую значение 200 для параметра totalRequired (передано в .Take ()) и у меня есть 3 группы, связанные с этой кампанией, то для каждой группы потребуется 200, а не 200 общие данные из каждой группы, связанной с кампанией.
В SQL я мог бы достичь этого с помощью запроса:
select * from
(
select [t1].EmailAddress, ROW_NUMBER() over(order by CampaignID desc) as [RowNumber] from contacts as [t1]
inner join contactgroupmapping as [t2] on [t1].ID = [t2].ContactID
inner join campaigngroupsmapping as [t3] on [t3].ContactGroupID = [t2].GroupID
where [t3].CampaignID = @HighestPriorityCampaignID
) as [Results] where [Results].[RowNumber] between 500 and 3000
С помощью этого запроса я пролистываю объединенный набор контактов из каждой группы, связанной с конкретной кампанией. Поэтому мой вопрос: как я могу добиться этого, используя вместо этого синтаксис LINQ To SQL?