我熟悉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)
}
提前感谢您提供的任何帮助或指向您可能提供的其他信息来源。
答案 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)
});
完整的工作样本在这里..
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();
}