c # ASP.Net Core и Linq: агрегатные функции MIN и MAX - PullRequest
0 голосов
/ 02 мая 2019

Visual Studio 2019; ASP.Net Core 2.1

У меня есть система БД, в которой есть таблица событий, происходящих на разных машинах.

// pseudo code
eventLog (
    id int primary key not null,
    eventType varchar(16) not null,
    machineName varchar(64) not null,
    loggedInUser varchar(16) not null,
    eventDate datetime not null,
)

Я хочу получить самые ранние и самые последние даты событий для конкретной машины. В SSMS я могу получить информацию, которую хочу получить:

SELECT
       MIN([eventDate]),
       MAX([eventDate])
FROM eventLog
WHERE UPPER(machineName) LIKE 'MY-MACHINENAME%';

В пробном прогоне я получаю минимальное / максимальное значения:

2015-08-17 10:31:47.000 / 2019-05-02 12:54:20.000

Примечание: machineName может быть либо «простой» строкой, например «mypc», либо полным доменным именем («mypc.company.com»). Я выделил первый «пунктирный» сегмент возможного полного доменного имени и сравнил его с переменной myMachine, в которой уже были удалены все пунктирные части.

В C # я знаю, что есть Aggregate методы, но мне трудно следовать документам и примерам, которые я нашел, и воплощать их в реальную практику. У меня так далеко:

public class VisibleRange {
    public DateTime start { get; set; }
    public DateTime end { get; set; }
}

...

var ctx = userTrackingContext.EventLog;

usertrackingRange = (
    from eventLog in userTrackingContext.EventLog
    where eventLog.Machine.ToUpper().Split(
        '.',
        StringSplitOptions.RemoveEmptyEntries
    )[0].Trim().Equals(myMachine)
    select eventLog.Date
).Select(range => new VisibleRange {
    start = ctx.Min(a => a.Date),
    end = ctx.Max(a => a.Date)
}).First();

Это работает, но не дает мне полезных результатов для значения Min. Это примерно на 11 лет.

8/2/2004 8:05:27 PM  /  5/2/2019 12:00:00 AM  

Как преобразовать запрос SSMS в запрос LINQ?

Ответы [ 3 ]

2 голосов
/ 02 мая 2019

Вы можете попробовать как: -

        var range = new VisibleRange() { };

        var matched = userTrackingContext.EventLog.Where(a => a.MachineName.StartsWith(myMachine));

        if(matched != null)
        {
            range.start = matched.Min(a => a.EventDate);
            range.end = matched.Max(a => a.EventDate);
        }
0 голосов
/ 02 мая 2019

Я сделал быстрый тест на курение, и твои избранные работают на меня. Почему вы не вызываете range.Min и range.Max, чтобы получить результаты из вашего отфильтрованного набора данных?

var now = DateTime.Now;

var nums = new List<Num>
{
    new Num { Min = now, Max = now.AddDays(1) },
    new Num { Min = now.AddDays(10), Max = now.AddDays(50) },
    new Num { Min = now.AddDays(51), Max = now.AddDays(100) },
};

var minMaxNum = nums.Select(num => new Num
{
    Min = nums.Min(_ => _.Min),
    Max = nums.Max(_ => _.Max),
}).First();
0 голосов
/ 02 мая 2019

Вы можете попробовать следующий запрос LINQ

usertrackingRange = (
from eventLog in userTrackingContext.EventLog
where eventLog.Machine.ToUpper().Split(
    '.',
    StringSplitOptions.RemoveEmptyEntries
)[0].Trim().Equals(myMachine)
select eventLog.Date
).Select(range => new VisibleRange {
   start = ctx.OrderByAscending(a => a.Date).First(),
   end = ctx.OrderByDescending(a => a.Date).First()
}).First();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...