ASP.Net MVC Linq Группировка запросов

Я получаю последние 20 обновленных записей в базе данных, используя следующие

var files = (from f in filesContext.Files
                         join ur in filesContext.aspnet_Roles on f.Authority equals ur.RoleId
                         join u in filesContext.aspnet_Users on f.Uploader equals u.UserId
                         orderby f.UploadDate descending
                         select new FileInfo { File = f, User = u, UserRole = ur }).Take(20);

Затем я разделяю результаты на мой взгляд:

<%foreach(var group in Model.GroupBy(f => f.UserRole.RoleName)) {%>
//output table here

Это хорошо, так как таблица отображается для каждой из моих ролей. Однако, как и ожидалось, я получаю последние 20 записей в целом, как я могу получить последние 20 записей для каждой роли?

Итак, я заканчиваю с:

UserRole1

// Последние 20 записей, связанных с этим UserRole1

UserRole2

// Последние 20 записей, связанных с этим UserRole2

UserRole3

// Последние 20 записей, связанных с этим UserRole3

12.10.2009 21:50:17
2 ОТВЕТА
РЕШЕНИЕ

Я могу придумать три возможных способа сделать это. Сначала получите все роли, затем выполните запрос Take (20) для каждой роли, объединяя результаты в вашу модель. Это может быть или не быть много разных запросов в зависимости от количества ролей, которые у вас есть. Во-вторых, получите все результаты, а затем отфильтруйте последние 20 для каждой роли в вашем представлении. Это может быть очень большой запрос, занимающий много времени. В-третьих, получите большое количество результатов, которые, вероятно, будут содержать не менее 20 записей на роль (но это не гарантировано), а затем отфильтруйте последние 20 на роль в вашем представлении. Я бы, вероятно, использовал первый или третий варианты в зависимости от того, насколько важно получить 20 результатов.

var files = (from f in filesContext.Files
             join ur in filesContext.aspnet_Roles on f.Authority equals ur.RoleId
             join u in filesContext.aspnet_Users on f.Uploader equals u.UserId
             orderby f.UploadDate descending
             select new FileInfo { File = f, User = u, UserRole = ur })
           .Take(2000);


<% foreach (var group in Model.GroupBy( f => f.UserRole.RoleName,
                                     (role,infos) =>
                                         new {
                                               Key = role.RoleName,
                                               Selected = infos.Take(20)
                                             } ))                                           { %>

   <%= group.Key %>
   <% foreach (var selection in group.Selected)
      { %>
        ...
1
12.10.2009 22:24:02
Большое спасибо за ваши предложения. Я думаю, что вариант 3 будет лучшим методом для этой системы, так как в конечном итоге будет много ролей, и вставки в базу данных, скорее всего, будут распределены по всем ролям, поэтому захват количества должен покрыть это.
user188701 13.10.2009 12:40:41

Вы можете либо сосчитать элементы и пропустить первые (длина - 20) элементов, либо просто повернуть назад / взять 20 / повернуть назад.

foreach (var group in Model.GroupBy(f => f.UserRole.RoleName))
{
    // draw table header
    foreach (item in group.Reverse().Take(20).Reverse())
    {
        // draw item
    }

    // Or
    int skippedElementCount = group.Count() - 20;
    if (skippedElementCount < 0) skippedElementCount = 0;

    foreach (item in group.Skip(skippedElementCount))
    {
        // draw item
    }

    // draw table footer
}
0
12.10.2009 22:08:11