9

私は .Skip() および .Take() 拡張メソッドを LINQ To SQL でしばらくの間問題なく使用してきましたが、それらを使用したすべての状況で、常に単一のテーブルに対して使用されていました-次のように:

database.Users.Select(c => c).Skip(10).Take(10);

私の問題は、複数のテーブルから一連の結果を投影していて、セット全体をページングしたい (それでも DB でページングする利点を得たい) ことです。

私のエンティティモデルは次のようになります:

キャンペーン [多くの] グループ、グループ [多くの] 連絡先

これは、次のようなデータベース内の関係を通じてモデル化されます

キャンペーン -> CampaignToGroupMapping -> グループ -> GroupToContactMapping -> 連絡先

キャンペーンの詳細と、CampaignToGroupMapping を通じてキャンペーンに関連付けられた各連絡先のリストを保持するデータ構造を生成する必要があります。

Campaign
   CampaignName
   CampaignFrom
   CampaignDate
   Recipients
      Recipient 1
      Recipient 2
      Recipient n...

.SelectMany を使用して LINQ クエリを作成して、各グループの連絡先のセットを 1 つの線形データ セットに投影しようとしました。

私の試みは:

 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() に関して) がデータ セット全体ではなく、グループごとに発生していることです。

これは、パラメーターtotalRequired (.Take() に渡される)に値 200 を使用し、このキャンペーンに 3 つのグループが関連付けられている場合、各グループから 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 構文を使用してこれを達成するにはどうすればよいですか?

4

3 に答える 3

4

提供した SQL クエリを模倣するには、次のようにします。

var schedule = (from t1 in contacts
                join t2 in contactgroupmapping on t1.ID equals t2.GroupID
                join t3 in campaigngroupsmapping on t3.ContactGroupID = t2.GroupID
                where t3.CampaignID = highestPriority.CampaignID
                select new PieceOfCampaignSchedule
                {
                  Email = t1.EmailAddress
                }).Skip(500).Take(2500).ToList()

キャンペーン、受信者、またはその両方をページングしようとしていますか?

于 2009-04-23T16:23:31.453 に答える
0

あなたの試みは本当に近いと思います。何かが足りないかもしれませんが、Skip / Takeの前にSelectMany()を閉じる必要があると思います。

Recipients = c.CampaignGroupsMappings.SelectMany(d => d.ContactGroup.ContactGroupMappings.Select(e => new ContactData() { /*Contact Data*/ })).Skip(c.TotalSent).Take(totalRequired).ToList()

注:「/*連絡先データ*/})」の後に「)」を追加し、「。Take(totalRequired)」の後に「)」を削除しました

于 2009-04-23T19:23:25.297 に答える
0

ビューを使用して複数のテーブルからの結果を集計し、ビューに対して LINQ を使用します。

于 2009-04-23T12:55:31.623 に答える