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?

0
7 Reeds 2 Май 2019 в 23:10

3 ответа

Лучший ответ

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

        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);
        }
2
Vishnu 2 Май 2019 в 20:53

Вы можете попробовать следующий запрос 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();
0
Muhammad Hannan 2 Май 2019 в 20:17

Я быстро проверил дым, и твои избранные работают на меня. Почему вы не вызываете 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
Mitch Stewart 2 Май 2019 в 20:33