Группировать по имени в цикле MVC foreach для получения количества

#c# #asp.net-mvc #linq #razor

#c# #asp.net-mvc #linq #razor

Вопрос:

Приведенный ниже код — это то, что я сейчас запускаю в режиме razor.

 @foreach (var item in Model.intbyAnalysts.Select(x => x.Name).Distinct())
{
    <li>
        @Html.DisplayFor(x => item)
    </li>

}
  

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

     John 5 
    Sam  6 
    Mary 8 
    etc
  

Это не работает, но я думал о чем-то вроде приведенного ниже:

 @foreach (var item in Model.intbyAnalysts.GroupBy(x => x.Name)) {
    <td>
    @Html.DisplayFor(x => x.item))
    </td>    
    <td>
     @Html.DisplayFor(x => x.item.Count())
    </td>      
}
  

Опять же, это не работает, но я также думал о чем-то вроде приведенного ниже:

 @foreach (var item in Model.intbyAnalysts.GroupBy(x => x.Name)
                                          .Select(n => new {n.Name, n.Count }))
  

Любая помощь со стороны очень ценится.

Комментарии:

1. Ваш вопрос не о MVC и не о Razor. Вам просто нужно создать модель IEnumerable<(имя строки, количество входов)> и передать ее в представление. Почему вы используете «DisplayFor» и когда вы сказали «это не работает» — что не работает?

2. Мне было интересно, смогу ли я сделать это в запросе linq без создания другой модели. Что касается DisplayFor, я новичок в использовании razor pages, поэтому не уверен, каким будет наилучший способ отображения результатов.

3. Просто используйте @ symbol, затем укажите источник данных, например @Model . Элементы [0] и т.д. Всегда полезно создавать отдельную модель…

Ответ №1:

Переместите логику Linq в класс модели вместо того, чтобы помещать ее в view…

Это работает для меня, я думаю, нет необходимости объяснять этот простой код:

 using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp
{
    public class Program
    {
        public static void Main()
        {
            var model = new Model();
            model.Items.Add( new Item { Name = "item1" } );
            model.Items.Add( new Item { Name = "item1" } );
            model.Items.Add( new Item { Name = "item1" } );
            model.Items.Add( new Item { Name = "item2" } );
            model.Items.Add( new Item { Name = "item2" } );
            model.Items.Add( new Item { Name = "item3" } );

            foreach (var entry in model.ItemNameAndCount)
            {
                Console.WriteLine( entry.name   ": "   entry.count );
            }
        }

        public class Model
        {
            public List<Item> Items { get; set; } = new List<Item>();

            public IEnumerable<(string name, int count)> ItemNameAndCount
               => Items.GroupBy( x => x.Name )
                       .Select( group =>
                            (
                              name: group.Key,
                              count: group.Count()
                            )
                        );
        }

        public class Item
        {
            public string Name { get; set; }
        }
    }
}
  

Комментарии:

1. Зачем вам нужен item . Имя == группа. Ключевой предикат внутри Count? В любом случае это количество вернет количество элементов только в текущей группе.

Ответ №2:

Все кажется прекрасным, за исключением того, что оно должно быть @Html.DisplayFor(x => x.item.Key)) первым td (а не просто x.item ).

Устраняет ли это проблему для вас? Если нет, не могли бы вы обновить вопрос с некоторыми подробностями об ошибках.