Используя LINQ, как я могу группировать по «вычисляемому полю» - PullRequest
5 голосов
/ 21 декабря 2008

Я использую LINQ to EF и у меня следующий запрос LINQ:

var results = (from x in ctx.Items
               group x by x.Year into decades
               orderby decades.Count() descending
               select new { Decade = decades.Key, DecadeCount = decades.Count() });

Таким образом, это приводит меня туда, где я хочу быть, в том смысле, что я разбиваю предметы по годам и количеству предметов в этом году. (т.е. 2001 - 10, 1975 - 15, 2005 - 5, 1976 - 1) Хотя я действительно хочу сделать это, разбив их по десятилетиям (т.е. 2000 - 15, 1970 - 16).

Как получить «вычисляемое поле» в части «by» предложения group для оператора Linq. Я думаю, что я хочу что-то вроде:

var results = (from x in ctx.Items
               group x by (x => x.Year.Value.ToString().Substring(0, 3) + "0s") into decades
               orderby decades.Count() descending
               select new { Decade = decades.Key, DecadeCount = decades.Count() });

Или, в более общем смысле, синтаксис, чтобы я мог выполнить более сложную оценку / расчет для включения группы. Есть идеи?

РЕДАКТИРОВАТЬ (обновление):

(x => x.Year.Value.ToString (). Substring (0, 3) + «0s») - не работает - «LINQ to Entities не распознает метод» System.String ToString () ', и этот метод не может быть преобразован в выражение хранилища. "

(x.Year / 10 * 10) - Функционально работает (спасибо) - единственная «проблема» состоит в том, что «s» не заканчивается (то есть 1970 против 1970-х годов)

В любом случае можно ли поместить функцию в предложение by? то есть группа x по this.ManipulateYear (x.Year) на десятилетия ... или ... x => x.Year.Value.ToString (). Substring (0,3) + "0s" ?? Было бы неплохо иметь какую-то технику (например, вызов функции или использование лямбда-выражения), чтобы я мог охватить любой случай, о котором могу подумать.

Еще раз спасибо за помощь каждому.

Ответы [ 4 ]

7 голосов
/ 22 декабря 2008

Вы можете использовать предложение let, чтобы избежать многократного подсчета десятилетий:

from x in ctx.Items
group x by (x.Year / 10 * 10) into decades
let decadeCount = decades.Count()
orderby decadeCount descending
select new { Decade = decades.Key, DecadeCount = decadeCount }
6 голосов
/ 21 декабря 2008

Как насчет группировки по x.Year / 10? (не проверял это!)

var results = (from x in ctx.Items
               group x by (x.Year / 10 * 10) into decades
               orderby decades.Count() descending
               select new { Decade = decades.Key, DecadeCount = decades.Count() });

EDIT1: изменено (x.Year / 10) на (x.Year / 10 * 10), чтобы получить, например, 1980 вместо 198.

EDIT2: в вашем примере "группа x по x.Year.Value.ToString (). Подстрока (0, 3) +" 0s ") в десятилетия" также должна работать Нет необходимости в синтаксисе лямбы.

EDIT3: удалено лишнее * 10. Спасибо, Марк!

2 голосов
/ 12 октября 2009

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

Рассчитанные поля можно использовать в LINQ для объектов (чтобы вы могли вернуть все данные в виде объектов и затем выполнить группировку)

0 голосов
/ 21 декабря 2008

Я полагаю, вы бы связали метод SelectMany до конца вашего результата. Это возвращает IEnumerable из IEnumerables.

...