Вы указали в комментариях, что вы хотите фильтровать мой месяц/год, так что, кажется, нет необходимости включать эти столбцы в таблице и вместо этого вы можете использовать заголовок для таблицы, например «Результаты за апрель 2016 года».
Начните с определения просмотра моделей для представления хотим, чтобы вы хотите отобразить в представлении
public class MemberPaymentVM // for the table rows
{
public MemberPaymentVM(int categoryCount)
{
Amounts = new List<decimal>(new decimal[categoryCount]);
}
public string Name { get; set; }
public List<decimal> Amounts { get; set; }
public decimal Total { get; set; }
}
public class MonthPaymentsVM
{
[DisplayFormat(DataFormatString = "{0:MMMM yyyy}"]
public DateTime Date { get; set; }
public IEnumerable<string> Categories { get; set; }
public List<MemberPaymentVM> Payments { get; set; }
}
следующие запросы могут быть прикованным, но сломать это в каждом компоненте, первый фильтр данных
var date = new DateTime(2016, 4, 1);
var filtered = db.Payments.Where(x => x.PayDate >= date && x.PayDate < date.AddMonths(1));
Затем группируйте данные как Member
, так и Category
и суммируйте полученные результаты (я полагаю, что ваша модель Payment
содержит виртуальные свойства для отношений
var grouped = filtered.GroupBy(x => new { member = x.Member.ID, category = x.Category.ID }).Select(x => new
{
Member = x.First().Member,
Category = x.First().Category,
Amount = x.Sum(y => y.Amount)
});
Затем группа снова Member
для представления каждой строки таблицы
var data = grouped.GroupBy(x => x.Member.ID);
Далее, получить ваши категории
var categories = db.Categories;
var categoryCount = categories.Count();
var categoryIDs = categories.Select(x => x.CategoryId).ToList();
И сборки вы просмотра моделей
var model = new MonthPaymentsVM()
{
Date = date,
Categories = categories.Select(x => x.CategoryName),
Payments = new List<MemberPaymentVM>()
};
foreach(var group in data)
{
MemberPaymentVM payment = new MemberPaymentVM categoryCount);
payment.Name = group.First().Member.Name;
foreach (var item in group)
{
int index = categoryIDs.IndexOf(item.Category.CategoryId);
payment.Amounts[index] = item.Amount;
payment.Total += item.Amount;
}
model.Payments.Add(payment);
}
и, наконец, , верните модель на вид
return View(model);
И по мнению
@model MonthPaymentsVM
<h2>@Html.DisplayFor(m => m.Date);
<table>
<thead>
<tr>
<td>Name</td>
@foreach(var category in Model.Categories)
{
<td>@category</td>
}
<td>Total</td>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Payments)
{
<tr>
<td>@item.Name</td>
@foreach (var amount in item.Amounts)
{
<td>@amount</td> // @amount.ToString("c") to format it
}
<td>@item.Total</td>
</tr>
}
</tbody>
</table>
Вы хотите, чтобы это сгруппированных по имени пользователя и год и месяц (т.е. отображать строки для «John 2016 04» и «John 2016 03» и «John 2015 12» и т. д., или просто сгруппированы по имени пользователя и отфильтрованы в течение определенного месяца и года? –
сгруппированы по имени пользователя и отфильтрованы за определенный месяц и год – Diin
ОК, Нет времени только сейчас, но добавит ответ примерно через час. –