Я новичок в ASP.NET Core и работаю над проектом, в котором мне нужно группировать данные по неделям, используя Entity Framework Core (EF Core) с базой данных MySQL. Однако у меня возникла проблема с группировкой.
Вот запрос LINQ, который я использую:
from report in _context.DmarcReports
.Where(r => r.DomainName == request.Domain)
.Where(r => !request.BeginDate.HasValue || r.BeginDate >= request.BeginDate.Value)
.Where(r => !request.EndDate.HasValue || r.EndDate <= request.EndDate.Value)
join summary in _context.DmarcSummary
on report.ReportId equals summary.ReportId
join sourceLookup in _context.SourceLookup
on summary.SourceIp equals sourceLookup.Ip
let week = EF.Functions.DateDiffWeek(
EF.Functions.DateFromParts(report.BeginDate.Year, 1, 1),
report.BeginDate
) + 1
let year = report.BeginDate.Year
group summary by new { sourceLookup.SourceName, Week = week, Year = year } into g
select new
{
Date = EF.Functions.DateFromParts(g.Key.Year, 1, 1),
Date = new DateTime(g.Key.Year, 1, 1).AddDays((g.Key.Week - 1) * 7),
SourceName = g.Key.SourceName,
DMARCPassCount = g.Sum(x => x.DMARCVolume),
}
Я пытаюсь использовать EF.Functions.DateDiffWeek()
, чтобы вычислить номер недели для группировки. Однако я получаю следующую ошибку:
«DbFunctions» не содержит определения «DateDiffWeek», и не удалось найти доступный метод расширения «DateDiffWeek», принимающий первый аргумент типа «DbFunctions» (вам не хватает директивы using или ссылки на сборку?)
Я уже добавил необходимые директивы using:
using Microsoft.EntityFrameworkCore;
using Pomelo.EntityFrameworkCore.MySql;
Любые предложения о том, как решить эту проблему?
См. также документацию о функциях даты MySQL: dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html Да, я знаю, что вы используете Entity Framework, который может транслировать некоторые функции «внутри». " и запускать их и в других СУБД, но некоторые функции по-прежнему работают именно в той СУБД, для которой они были созданы.
@JonasMetzler Я использую базу данных Mysql.
Затем я бы попытался использовать функции, перечисленные в связанной документации.
@Ralf означает всплытие?
Функциональность MySql стала доступна в .Net как метод. Вам это открылось.
@AdiLIsmaiL типичный способ, используемый во всех базах данных, — использовать таблицу «Календарь», присоединиться к ней и сгруппировать ее по месяцу, неделе, семестру, триместру или любому другому полю отчетного периода, которое вы хотите. Это типичный способ создания отчетов по времени во всех базах данных отчетов и хранилищах данных.
@AdiLIsmaiL Вам также не обязательно выполнять JOIN в LINQ, на самом деле это ужасная идея. Вы можете создать представление, которое объединяется с таблицей «Календарь» или измерением «Дата», и сопоставить его. ORM, такие как EF, предназначены для загрузки графиков объектов, а не для создания сложных запросов отчетов.
from report in _context.DmarcReports
.Where(r => r.DomainName == request.Domain)
.Where(r => !request.BeginDate.HasValue || r.BeginDate >= request.BeginDate.Value)
.Where(r => !request.EndDate.HasValue || r.EndDate <= request.EndDate.Value) join summary in _context.DmarcSummary
on report.ReportId equals summary.ReportId join sourceLookup in _context.SourceLookup
on summary.SourceIp equals sourceLookup.Ip let weekDifference = (report.BeginDate - new DateTime(report.BeginDate.Year, 1, 1)).Days / 7 + 1 let year = report.BeginDate.Year group summary by new { sourceLookup.SourceName, Week = weekDifference, Year = year } into g select new {
Date = new DateTime(g.Key.Year, 1, 1).AddDays((g.Key.Week - 1) * 7),
SourceName = g.Key.SourceName,
DMARCPassCount = g.Sum(x => x.DMARCVolume),};
В этом модифицированном запросе WeekDifference вычисляет разницу в неделе между report.BeginDate и первым днем года. Это значение затем используется для группировки. Остальная часть запроса остается неизменной.
Это должно решить проблему и позволить эффективно группировать данные по неделям.
Вы действительно используете базу данных MySQL? Эти функции
DateDiffWeek
иDateFromParts
являются функциями для базы данных SQL Server. Поэтому я предполагаю, что вам нужно использовать другие функции, поддерживаемые MySQL. Или вы используете MSSQL, а не MySQL?