0

我熟悉 LINQ 的大部分功能,但似乎无法弄清楚如何在单个 LINQ 查询中返回多页数据的投影。

这是场景......我正在构建一个“邮件合并”,其中每个字母都包含一个表格,但该表格仅限于 40 行信息。因此,如果特定收件人的表格信息包含 100 行,我希望返回三个投影对象;一个用于前 40 行,包括收件人,一个用于后 40 行,同样包括同一收件人,一个用于最后 20 行具有相同收件人。

Recipient A: Table Rows: 50
Recipient B: Table Rows: 100
Recipient C: Table Rows: 20

The iteration results that I want are:
{
    Recipient: A,
    Table: (rows 0-39)
},
{
    Recipient: A,
    Table: (rows 40-49)
},
{
    Recipient: B,
    Table: (rows 0-39)
},
{
    Recipient: B,
    Table: (rows 40-79)
},
{
    Recipient: B,
    Table: (rows 80-99)
},
{
    Recipient: C,
    Table: (rows 0-19)
}

提前感谢您提供的任何帮助或指向您可能提供的其他信息来源的指示。

4

1 回答 1

0

在提出更好的替代方案之前,您可以使用以下方法。

var q = db.Recipients;

// this loads all table rows...
// so you should filter q as per 
// needed rowset only
        var listq = q
           .SelectMany(x => 
               x.Table.Select( (y,i)=> new {
                  Key = y.RecipientID + "-" + ((int)i/(int)40),
                  Value = y
               })
           );

        var model = listq.GroupBy(x=>x.Key)
           .Select( x=> new {
               Recipient = x.Select(y=>y.Value.Recipient).First(),
               Table = x.Select(y=>y.Value)
           });
  1. 在第一步中,我们将从数据库中获取所有具有表格导航属性的记录。
  2. 接下来,我们将调用 SelectMany 来展平层次结构,但是,我们将创建一个新的 Key,其中包含 RecipientID 和除以 40 的索引,因此第一个 Recipient 为 1,索引为 1,因此 Key 将为 1-0,依此类推对于第 41 个索引,Key 将为 1-1。
  3. 然后我们将按新创建的 Key 进行分组,
  4. 然后我们将通过选择第一个收件人和枚举表中的其余部分来选择收件人和表。

完整的工作样本在这里..

    public class Recipient
    {
        public Recipient()
        {
            Table = new List<Table>();
        }
        public long RecipientID { get; set; }
        public List<Table> Table { get; set; }
    }

    public class Table
    {
        public long TableID { get; set; }
        public long RecipientID { get; set; }
        public Recipient Recipient { get; set; }
    }

    private static void Add(List<Recipient> list, long index, int p2)
    {
        Recipient r = new Recipient
        {
            RecipientID = index
        };
        for (int i = 0; i < p2; i++)
        {
            Table t = new Table
            {
                TableID = i,
                Recipient = r,
                RecipientID = r.RecipientID
            };
            r.Table.Add(t);
        }
        list.Add(r);
    }

    static void Main(string[] args)
    {

        List<Recipient> list = new List<Recipient>();

        Add(list, 1, 80);
        Add(list, 2, 15);
        Add(list, 3, 99);

        var listq = list
           .SelectMany(x => 
               x.Table.Select( (y,i)=> new {
                  Key = y.RecipientID + "-" + ((int)i/(int)40),
                  Value = y
               })
           );

        var model = listq.GroupBy(x=>x.Key)
           .Select( x=> new {
               Recipient = x.Select(y=>y.Value.Recipient).First(),
               Table = x.Select(y=>y.Value)
           });


        foreach (var item in model)
        {
            Console.WriteLine("{0}={1}",item.Recipient.RecipientID,item.Table.Count());
        }

        Console.ReadLine();
    }
于 2013-10-26T11:46:07.067 回答