Używam metod rozszerzających .Skip() i .Take() z LINQ To SQL od dłuższego czasu bez żadnych problemów, ale we wszystkich sytuacjach, w których je używałem, zawsze był jeden stół - takie jak:LINQ do SQL Paging
database.Users.Select(c => c).Skip(10).Take(10);
Moim problemem jest to, że jestem teraz wystające komplet wyników z wielu tabel i chcę strony na ogólny zestaw (i nadal uzyskać korzyści z stronicowania w DB) .
Mój model podmiot wygląda następująco:
kampania [ma wiele] Grupy, grupa [ma wiele] kontaktów
ten jest modelowany za pomocą relacji w bazie danych jak
Kampania -> CampaignToGroupMapping -> Grupa -> GroupToContactMapping -> Kontakt
Potrzebuję wygenerować strukturę danych lding szczegóły kampanii i również listę każdego kontaktu związanego z kampanią przez CampaignToGroupMapping, tj
Campaign
CampaignName
CampaignFrom
CampaignDate
Recipients
Recipient 1
Recipient 2
Recipient n...
próbowałem napisać kwerendę za pomocą LINQ .SelectMany do projektu zbiór kontaktów z każdej grupy do jeden zestaw danych liniowych, w nadziei, że mógłbym .Skip() .Take() z tego.
Moja próba była:
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();
Problemem jest to, że stronicowania (w odniesieniu do Skip() i Take()) dzieje się dla każdej grupy, a nie całego zestawu danych.
Oznacza to, że jeśli użyję wartości 200 dla parametru totalRequired (przekazywany do .Take()) i mam 3 grupy powiązane z tą kampanią, to zajmie to 200 z każdej grupy - nie 200 z łącznej ilości danych z każdej grupy powiązanej z kampanią.
W SQL, można to osiągnąć z zapytaniem, takie jak:
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
Z tego zapytania, ja przywoławczą w połączeniu zespołu styków z każdej grupy związanej z danym kampanii. Moje pytanie brzmi: jak mogę to osiągnąć, używając zamiast tego składni LINQ To SQL?
Idealnie szukałem rozwiązania wykorzystującego LINQ do SQL.Jak wspomniałem w mojej odpowiedzi, mogłem po prostu wykonać zapytanie SQL bezpośrednio z ADO.NET też - ale chciałem użyć LINQ To SQL dla spójności z innym kodem.Dzięki za sugestię – Martin
LINQ do SQL obsługuje widoki.Po prostu przeciągnij i upuść je do projektanta.Zrozumiałem, że chcesz LINQ do rozwiązania SQL.Zadziałem ci stworzyć widok do użycia przez LINQ do architektury SQL – rguerreiro