#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
резервных полей свойств.