Как динамически сгруппировать список в зависимости от роли в asp.net mvc - PullRequest
0 голосов
/ 05 августа 2010

Вот мой сценарий: нам нужна страница со списком доноров, в зависимости от пользователя, просматривающего страницу, которую мы хотим сгруппировать, по уровню донора или просто по имени сортировки.Меня смущает то, что мы хотели бы сгруппировать автономных доноров и дать счет на основе группировки.

В моем контроллере у меня есть

 [HttpGet]
        public ActionResult Society(string id)
        {
            var society = _db.ONLINEDR_DONOR_LIST
                .Include("ONLINEDR_DONORS")
                .Single(s => s.DONOR_LIST_ID == id);

            var donors = _db.ONLINEDR_DONORS
                .Where(d => d.DONOR_LIST_ID == id)
                .OrderBy(d => d.SUBGROUP_SORT)
                .ThenBy(d => d.SORT_NAME)
                .ToList();
            if (User.Identity.Name == "public")
            {
                //First off, check to make sure the list is viewable.
                if (society.PUBLIC_IND == "N")
                    RedirectToAction("Index", "Home");
                donors = _db.ONLINEDR_DONORS
                    .Where(d => d.DONOR_LIST_ID == id)
                    .OrderBy(d => d.SORT_NAME)
                    .ToList();
            }
            var viewModel = new SocietyDetailViewModel()
            {
                Society = society,
                Donors = donors
            };

            return View(viewModel);
        }

Я хотел бы иметьчто-то вроде

donors = _db.ONLINEDR_DONORS
     .Where(d => d.DONOR_LIST_ID == id)
     .GroupBy(d => d.SORT_NAME)
     .ToList();

, которое я могу передать в свое представление, а затем как-то показать в представлении

<% if (Model.donor.GroupedByItemCount > 1) { %>
<%: Model.donor.GroupedByItemCount %>
<% } %

(я все еще новичок в asp.net MVC и LINQ, так что любые полезныессылки на объяснение того, что я делаю неправильно, также будут оценены).

Большое спасибо.

1 Ответ

0 голосов
/ 05 августа 2010

В объявлении переменной donors компилятор может определить тип donors как List<Donor>

В назначении в желаемом коде доноры должны быть List<IGrouping<string, Donor>>

donors не может быть одновременно обоих типов.


Предположим, у вас есть этот запрос:

List<IGrouping<string, Donor>> donors = _db.ONLINEDR_DONORS
  .Where(d => d.DONOR_LIST_ID == id)
  .GroupBy(d => d.SORT_NAME)
  .ToList(); 

Этот запрос является локальным и дает вам ключи:

donors.Select(g => g.Key)

Этот запрос в смешанном режиме. Запрос отправляется в базу данных для каждого элемента в списке, чтобы получить его счет. Это потенциальная проблема производительности.

donors.Select(g => g.Count())

Такое поведение обусловлено различием между linqToObjects groupby и sql groupby.

  • В sql groupby вы получаете ключ и агрегаты - без элементов.
  • В LinqToObjects вы получаете ключ и элементы группы - и можете вычислять агрегаты из элементов.

Предположим, у вас есть этот запрос:

List<IGrouping<string, Donor>> donors = _db.ONLINEDR_DONORS
  .Where(d => d.DONOR_LIST_ID == id)
  .ToList()
  .GroupBy(d => d.SORT_NAME)
  .ToList();

В приведенном выше запросе записи сначала гидратируются, а затем группируются локально. Все запросы по результату локальные.

Этот запрос формирует данные результата от IGrouping<string, Donor> до GroupShape. GroupShape - это класс, который вы создаете, который имеет свойства SortName и Count.

donors.Select(g => new GroupShape()
{
  SortName = g.Key,
  Count = g.Count()
});

Предположим, у вас есть этот запрос:

List<GroupShape> donors = _db.ONLINEDR_DONORS 
  .Where(d => d.DONOR_LIST_ID == id) 
  .GroupBy(d => d.SORT_NAME) 
  .Select(g => new {SortName = g.Key, Count = g.Count()})
  .ToList()
  .Select(x => new GroupShape()
  {
    SortName = x.SortName,
    Count = x.Count
  }).ToList();

Здесь группировка и подсчет выполняются в базе данных. Каждая строка сначала гидратируется в анонимный экземпляр, а затем копируется в экземпляр GroupShape (класс, который вы создаете).

...