繁体   English   中英

c# ASP.Net Core 和 Linq:聚合函数 MIN 和 MAX

[英]c# ASP.Net Core and Linq: aggregate functions MIN and MAX

Visual Studio 2019; ASP.NET 核心 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”或 FQDN(“mypc.company.com”)。 我拆分出可能的 FQDN 的第一个“虚线”段,并将其与已删除任何虚线部分的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();

这运行但没有为我提供最小值的有用结果。 这大约是 11 年。

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

如何将 SSMS 查询转换为 LINQ 查询?

你可以尝试像:-

        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);
        }

您可以尝试以下 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();

我做了一个快速的烟雾测试,你的选择对我有用。 为什么不调用 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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM