LINQ-запрос с SELECT и двумя условиями GROUP-BY
Какова эквивалентная инструкция LINQ для Datatable
следующего SQL-запроса:
SELECT code_direction, count(TP) AS CN
FROM table1
WHERE cod_time = 'A011'
GROUP BY TP,code_direction;
и как получить результат в новую таблицу данных?
Я пытался преобразовать его, но у меня есть некоторые ошибки. Кто-то может взглянуть на это:
var query = from t in table1.AsEnumerable()
group t by new { t.TP, t.code_direction }
into grp
select new
{
grp.Key.code_direction,
CN = grp.Count(t.TP)
};
foreach (var x in query)
{
Console.Write(x.code_direction);
Console.Write(x.CN);
}
2 ответа
Насколько ваш первый вопрос идет. LINQ-эквивалент SQL-запроса:
var query = from t in table1.AsEnumerable()
where t.cod_time == "A011"
group t by new { t.TP, t.code_direction }
into grp
select new
{
grp.Key.code_direction,
CN = grp.Count()
};
Обратите внимание, что вам не нужно передавать аргументы grp.Count()
, (По очевидной причине, что в SQL COUNT(TP) совпадает с COUNT(*), то есть просто подсчитайте количество строк. История будет другой, если вы будете использовать COUNT(DISTINCT TP) или аналогичный.)
Что касается второго вопроса, если ваш запрос только что вернул IEnumerable<T>
где Т есть DataRow
(то есть запрос как table1.AsEnumerable().Where(r => r.cod_time == "A011")
) тогда вы могли бы просто DataTableExtensions.CopyToDataTable
метод расширения. Поскольку ваш запрос возвращает анонимный тип, вы должны будете следовать этим инструкциям, найденным в MSDN.
Я использовал LINQ для работы с объектом JSON, возвращенным из удаленного веб-сервиса sharepoint. Я отправил это, потому что большинство ответов, которые я нашел онлайн, немного отличалось от того, что мне было нужно.
JSON-список ежедневных действий возвращается из списка удаленных ресурсов и затем суммируется с помощью LINQ
Упрощенная версия определения пользовательского объекта показана ниже (& определяется в области моделей приложения MVC).
public class MyCustomObjectList
{
public string eventdate { get; set; }
public string userid { get; set; }
public string action { get; set; }
}
Объект JSON сериализуется в массив MyCustomObjectList.
var customobject = serializer.Deserialize<MyCustomObjectList>(jsonobject);
Я хотел выяснить, сколько действий каждого типа произошло в данный день. Примечание: дата события сохраняется в виде строки в формате гггг-мм-дд чч: мм: сс. Это должно было упростить преобразования между C#, JSON и Jquery (где требуется, я создаю объекты DateTime в другом месте кода, используя дату события.
Некоторые утверждают, что это неэффективно, но я предпочитаю разделять процессы на последовательный набор действительно простых операций, чтобы упростить отладку и помочь другим людям следовать моему коду. Вот почему есть 2 запроса Linq.
querya удаляет компонент времени из даты события. Это гарантирует, что наша последующая группировка произойдет по дням, а не по секундам. Чтобы быть вдвойне уверенным в отсутствии кеширования, я создаю его в новом поле, называемом actionday. Я также переименую действие в действие, потому что intellisense запутался!! Остальные столбцы копируются как есть.
var querya =
from c in customobject.rows
select new { actionday = c.eventdate.Substring(0, 10), activity = c.action, c.userid,
c.eventdate };
/ * queryb создает сгруппированный счетчик querya, сгруппированный по actionday & activity, создающий новые столбцы actionkey,ActionCount,Dte,action & DetailList (который является сводкой для целей отладки) */
var queryb=
from p in querya group p by new { p.actionday, p.activity} into idGroup
actionkey = idGroup.Key,
ActionCount = idGroup.Count(),
Dte = idGroup.Key.actionday,
action = idGroup.Key.activity,
DetailList = idGroup
};
Вот версия, которая суммируется на 3 столбца
var queryc = from p in querya
group p by new { p.actionday, p.userid, p.activity} into idGroup
select new
{
actionday = idGroup.Key,
ActionCount = idGroup.Count(),
userid = idGroup.Key.userid,
Dte = idGroup.Key.actionday,
action = idGroup.Key.activity,
DetailList = idGroup
};