Как создать структуру,подобную списку?

#c# #entity-framework #asp.net-core #oop

Вопрос:

Извините за форму вопроса, так как я не знаю, как называется это понятие. Если будут какие — либо предложения, я их изменю.

Я просматриваю модель VMHome , и мне нужно сделать один из ее реквизитов таким

 List<string,string,int> 
 

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

Это в основном можно сделать так при использовании var

введите описание изображения здесь

после моей попытки это выглядит так при использовании view model

введите описание изображения здесь

и вот моя попытка создать «неизменяемую структуру»

 public class VMHome
{
    
    public List<categoryListPostCount> CategoryListPostCount { get; set; }

    // immutable struct
    public struct categoryListPostCount
    {
        public categoryListPostCount(string categoryName, string categoryID, int count)
        {
            CategoryName = categoryName;
            CategoryID = categoryID;
            Count = count;
        }

        public string CategoryName { get; set; }
        public string CategoryID { get; set; }
        public int Count { get; set; }
    }

}
 

И вот неправильное использование

 // ... inject vmHome.. and then 
vmHome.CategoryListPostCount = 
    (from cat in context.postCategories
    join con in context.postContents
    on cat.Id equals con.postCatId
    group new { cat, con } by new { con.postCatId, cat.categoryName } into g
    select new
    {
        //g.Key,
        CategoryName = g.Key.categoryName.ToString(),
        CategoryID = g.Key.postCatId.ToString(),
        Count = g.Count()
    }).ToList();
 

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

1. Вы создаете анонимный объект вместо экземпляра своей структуры. Вызовите свой конструктор структуры вместо new { ... } .

2. Другие уже указывали на ошибку (создание анонимного объекта вместо структуры), но у меня есть другое предложение: вы можете использовать record для более краткого объявления своего типа, например: public sealed record categoryListPostCount(string CategoryName, string CategoryID, int Count) ;

3. Я согласен с @MatthewWatson: использование dot net 5 запись может быть лучшей альтернативой, чем кортеж значений или анонимный тип.

4. @ZoharPeled не могли бы вы показать мне пример, как им пользоваться?

5. существует множество примеров того, как использовать записи в Интернете….

Ответ №1:

Вы выбираете результат своего запроса в анонимном типе. Вы должны создать тип вашего struct использования new VMHome.categoryListPostCount .

 vmHome.CategoryListPostCount = 
    (from cat in context.postCategories
    join con in context.postContents
    on cat.Id equals con.postCatId
    group new { cat, con } by new { con.postCatId, cat.categoryName } into g
    select new VMHome.categoryListPostCount
    {
        CategoryName = g.Key.categoryName.ToString(),
        CategoryID = g.Key.postCatId.ToString(),
        Count = g.Count()
    }).ToList();
 

Ответ №2:

современная dot net поддерживает кортежи значений (запущенные в dot net framework 4.7), что в основном обеспечивает неизменяемые структуры из коробки для 8 свойств.

Поэтому вместо a List<string,string,int> вы можете использовать List<(string,string,int)> — или даже лучше — название своих свойств: List<(string CatgoryName,string CategoryId, int Count)>

Другим вариантом было бы использовать анонимные типы, которые поддерживаются с момента появления linq (имеется в виду .Net 3 IIRC). Недостатком является то, что вы не можете объявить список анонимных типов таким же образом, вы должны использовать var .
иногда это более удобно, иногда менее читабельно.

Кроме того, созданная вами структура не является неизменяемой — неизменяемость означает, что значения ее свойств не могут быть изменены после ее создания. В c# 9 или выше вы можете использовать {get;init;} неизменяемые свойства, в c# 6 или выше вы можете использовать {get;} неизменяемые свойства, а в более ранних версиях вы можете добиться неизменности только с помощью явных readonly резервных полей свойств.