计算最大并发用户登录;使用LINQ和DateTime对象

本文关键字:LINQ 使用 DateTime 对象 登录 并发 用户 计算 | 更新日期: 2023-09-27 18:16:12

我在以下场景下创建查询的适当方法遇到了麻烦:

我想找到在任何给定点登录到一个假设系统的"用户"的最大数量。如果在给定的时间段内,同时登录的人数最多是5,那么我的查询应该返回5。

我正在使用LINQ,并认为自己是初学者;这是我尝试过的最高级的查询。

我的用户存储在一个描述为User_Logged_In_Table(user_id, begin_date_time, end_date_time)的数据库表中。User_ID是一个整数,begin_date_time和end_date_time是DateTime c#对象。

我目前的理解是:

myFunction(begin_time, end_time) //<- These two variables represent the threshold of time I am querying about.
{
    var u = from users in database.User_Logged_In_Tables
            where (users.begin_date_time.CompareTo(begin_time) > 0)
                  && (users.begin_date_time.CompareTo(end_time) < 0)
            select users;
            //The above tells me the users who have been logged in between those two times
            //however it does not tell me anything about their concurrency.
}

我在这一点上卡住了,不确定如何继续我需要的查询。

任何提示或建议都非常感谢!我也愿意进一步解释我的情况,如果我有不清楚的地方。

计算最大并发用户登录;使用LINQ和DateTime对象

"任何给定的时间段"是模糊的,所以你必须锁定它,比如说你将查看开始参数和结束参数之间的每个分钟时间,然后你将在这些分钟内获取并发登录的平均数量,以确定"总体"平均值。

现在,您将初始化一个int列表,然后循环遍历参数start time,每次循环添加一分钟,直到达到最大值。在该循环中,您将查找在该分钟内开始或仍在该分钟内继续的不同登录。您将获取Distinct() user_ids(以便一个用户在5秒内登录两次仍然算作1次登录),并将该Distinct计数添加到int列表中。

最后,您将得到一个int列表,该列表与startTime和endTime之间的分钟数一样长,并且可以使用Average()调用该列表以查看每给定分钟的平均登录数。

我想我现在可以分享这个答案了。这似乎是一个标准问题,我在http://www.haikulabs.com/Schedu10.htm上发现了一些有趣的东西。基本上,你的"预订"是你的登录会话,你的"房间"是你的HTTP连接。

要找到处理用户的最小连接数(即最大并发用户数),您需要根据您想要的分辨率在for循环和.AddMinutes.AddHours中测试DateTime。

现在,上面的内容是不准确的——有可能在你测试的值之间有一个短暂的会话,而你会错过它。因此,为了使其100%准确,您需要针对会话开始或结束的所有DateTimes进行测试,而不是针对每轮分钟或每轮小时进行测试。

上述基于离散时间间隔的查询解决方案很好,我在自己的一些工作应用程序中使用了相同的方法。

然而,需要注意的一点是,并发用户的数量仅在用户登录或退出时改变。此外,并发用户的数量只有在用户登录时才会增加(很抱歉,我的评论很明显,但我想确保自己也清楚这一点)。因此,创建一个LINQ查询就足够了,该查询可以遍历初始搜索找到的每个用户(具有范围限制),并检查在每个"登录时间"有多少用户登录,并从中获取最大数量。下面的实际LINQ(下面的代码是在VB。Net,并使用我自己的字段名,因为这是我必须测试的,如果这是一个问题,我道歉):

首先,要获得每个登录点的并发用户列表,我们有:

Dim listOfConcurrent =
    From row As DataRow In userRange
    Select New hlxListItem(Of DateTime)(
        row.Field(Of DateTime)("CiDateStart"),
        (From subRow In userRange
        Where subRow.Field(Of DateTime)("CiDateStart") <=
                row.Field(Of DateTime)("CiDateStart") AndAlso
            subRow.Field(Of DateTime)("CiDateEnd") > row.Field(Of DateTime)("CiDateStart")
        Select subRow).Count)

或者,您可以获得具有最高数量的" hlxlisttitem "以获得最大并发用户:

Dim maxConcurrent =
    (From row As DataRow In userRange
    Order By (From subRow In userRange
        Where subRow.Field(Of DateTime)("CiDateStart") <=
                row.Field(Of DateTime)("CiDateStart") AndAlso
            subRow.Field(Of DateTime)("CiDateEnd") > row.Field(Of DateTime)("CiDateStart")
        Select subRow).Count Descending
    Select New hlxListItem(Of DateTime)(
        row.Field(Of DateTime)("CiDateStart"),
        (From subRow In userRange
        Where subRow.Field(Of DateTime)("CiDateStart") <=
                row.Field(Of DateTime)("CiDateStart") AndAlso
            subRow.Field(Of DateTime)("CiDateEnd") > row.Field(Of DateTime)("CiDateStart")
        Select subRow).Count)).First()

所以,最后只是对上面的一些注释。hlxlisttitem只是一个简单的对象,带有一个通用字段和一个文本字段。本例中的泛型字段保存日期(登录时间),文本字段保存并发用户的数量。如果我有时间,我可以试着把上面的例子编辑成c#,并使用你的字段名,但我发布上面的原因是我可以确认它是有效的。如果以上对你有帮助,或者你需要任何额外的帮助,请告诉我。