如何构建LINQ(EF)查询以投影数据页面

时间:2013-10-26 07:00:56

标签: c# linq entity-framework

我熟悉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)
}

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

1 个答案:

答案 0 :(得分: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和index除以40,因此第一个Recipient为1,index为1,因此Key为1-0 ,对于第41个索引,Key将是1-1。
  3. 然后我们将按照新创建的Key进行分组,
  4. 然后我们将通过选择第一个收件人并在表中枚举其余来选择收件人和表。
  5. 完整的工作样本在这里..

        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();
        }