#linq-to-sql #foreach #grouping
#linq-to-sql #foreach #группировка
Вопрос:
У меня есть таблица элементов, которая содержит поле CategoryID. Это FK в таблицу категорий. Я хочу сгруппировать свои элементы по идентификатору категории и вернуть элементы и Categories.Name .
Я знаю, что могу сделать это на C#:
var ItemsByCat =
from i in Items
group i by i.CategoryId into g
select g
foreach(var n in ItemsByCat)
{
blah, blah
}
Мой вопрос — есть ли способ получить значения элементов в рамках группировки без необходимости повторять цикл? Что-то вроде:
from i in Items
group i by i.CategoryId into g
select new {
CategoryID = g.Key,
CategoryName = ???,
Items = ???
}
Большое спасибо,
BK
Ответ №1:
Я думаю, это то, что вы ищете:
from i in Items
group i by i.CategoryId into g
select new
{
CategoryID = g.Key,
CategoryName = g.First().Category.Name,
Items = g
}
РЕДАКТИРОВАТЬ: я надеюсь, что это ответ на ваш вопрос из комментариев.
g
это коллекция элементов, сгруппированных по их CategoryId
. Items
в select
может быть проекция, включающая любое подмножество Item
свойств, которые вам требуются. Пример:
from i in Items
group i by i.CategoryId into g
select new
{
CategoryID = g.Key,
CategoryName = g.First().Category.Name,
Items = g.Select(a => new{a.ItemID, a.ItemName})
}
Комментарии:
1. Ах, я понял — значит, g — это коллекция и с помощью . Сначала () я могу просто захватить CategoryName . Большое спасибо!
2. Точно. g — это просто еще один тип коллекции, который реализует
IEnumerable
. Я рад, что помог.3. Последний вопрос — что, если элементы в select были коллекцией объектов с элементами. ItemId, Items.Name ? Другими словами, я не хочу возвращать коллекцию целых записей элементов, а только подмножество полей элементов.
4. Я добавил к своему ответу некоторую информацию, которая, как я думаю, отвечает на ваш вопрос. Дайте мне знать.
5. Прямо идеально! Еще раз спасибо.
Ответ №2:
Как насчет объединения в таблицу категорий?
from i in Items
join c in Categories on i.CategoryId equals c.Id
group i by i.CategoryId into g
select new {
CategoryID = g.Key,
CategoryName = c.Name,
Items = i
}
Ответ №3:
CategoryName
должно быть i.Category.CategoryName //the name property
учитывая, что у вас есть правильная настройка отношений.
Элементы должны быть значениями group by , не уверен, зачем вам нужно делать это снова.
Комментарии:
1. После группировки i больше не находится в области видимости. Все, с чем мне нужно работать, это g .
2. да, это то, что я имел в виду, значения каждого элемента в g сгруппированы по элементам. Каждая сгруппированная запись имеет ключ и элементы (это ваши элементы, lol)
Ответ №4:
Предполагая, что у вас есть коллекция категорий в переменных categories, это будет выглядеть так:
var ItemsByCategory =
from i in items
join c in categories on i.CategoryId equals c.Id
group i by i.CategoryId into g
select new {
CategoryId=g.Key,
CategoryName=c.Name,
Items=g.Items
}
Комментарии:
1. Это предполагает, что вы не используете Entity Framework. В EF вы просто просматриваете свои свойства навигации, объединения не требуются.
2. Я думаю, что c выходит за рамки, как только я выполняю группировку. Если я перемещу объединение ниже группировки и присоединюсь к категориям на c.CategoryID = g.Key, похоже, это сработает. Это хороший подход?
3. Это нормально… Я нахожу странным, что это не работает по-другому, хотя, возможно, так оно и анализируется.