简体   繁体   English

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

[英]Calculating max concurrent “User Logins” using LINQ and DateTime objects

I am having trouble coming up with a proper way to create a query under the following scenario: 在以下情况下,我想不出一种正确的方法来创建查询:

I want to find the maximum amount of "users" logged into a hypothetical system at any given point. 我想找到在任何给定时间点登录到假设系统的“用户”的最大数量。 If, throughout a given period of time, the most peopled logged in at the same time was 5, my query should return 5. 如果在给定的时间内,同时登录的人数最多的是5,则我的查询应返回5。

I am using LINQ and would consider myself a beginner; 我正在使用LINQ,并且会认为自己是初学者; this is the most advanced query I have attempted. 这是我尝试过的最高级的查询。

My users are stored in a Database table described like User_Logged_In_Table(user_id, begin_date_time, end_date_time). 我的用户存储在描述为User_Logged_In_Table(user_id,begin_date_time,end_date_time)的数据库表中。 User_ID is an integer, and begin_date_time and end_date_time are DateTime C# objects. User_ID是整数,begin_date_time和end_date_time是DateTime C#对象。

My current understanding takes me about this far: 我目前的理解使我了解了这一点:

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.
}

I am stuck at this point, unsure of how to continue the query with what I need. 我被困在这一点上,不确定如何继续用我需要的查询。

Any hints, or suggestions are much appreciated! 任何提示或建议,不胜感激! Also I am willing to further explain my situation if I have been unclear in any area. 如果在任何地方都不清楚,我也愿意进一步解释我的情况。

So I think I could share this as an answer now. 所以我想现在可以分享这个答案。 It seems that this is a standard problem, I found something interesting on http://www.haikulabs.com/Schedu10.htm . 看来这是一个标准问题,我在http://www.haikulabs.com/Schedu10.htm上找到了一些有趣的东西。 Basically, your "reservations" are your log-in sessions and your "rooms" are your HTTP connections. 基本上,您的“预订”是您的登录会话,而您的“房间”是您的HTTP连接。

To find the minimum number of connections to handle your users (so, max concurrent users), you would need to test against a DateTime in a for loop and .AddMinutes or .AddHours depending on the resolution you want. 若要查找处理用户的最小连接数(因此,最大并发用户数),您将需要针对for循环中的DateTime和.AddMinutes.AddHours进行测试,具体取决于所需的分辨率。

Now, the above won't be accurate - it's possible that there's a short session right between the values you are testing and you'll miss it. 现在,以上内容并不准确-您测试的值之间可能会进行短暂的对话,而您会错过它。 So to make it 100% accurate, you need to test against all DateTimes where a session has either started or ended and not against every round minute or every round hour. 因此,要使其准确度达到100%,您需要针对会话开始或结束的所有DateTimes进行测试,而不要针对每一分钟或每一小时进行测试。

"Any given period of time" is vague, so you'll have to lock it down, like by saying you will look at each minute of time in between the start param and the end param, and you will take the average number of concurrernt logins among those minutes to determine the "overall" average. “任何给定的时间段”都是模糊的,因此您必须将其锁定,例如说您将查看开始参数和结束参数之间的每分钟时间,并且您将获得平均并发次数在那几分钟内登录,以确定“总体”平均值。

So now, you'll initialize a list of ints, then loop thru the param start time, adding a mintute for each loop, until you are at the max. 因此,现在,您将初始化一个int列表,然后循环遍历参数开始时间,为每个循环添加一个minute,直到达到最大值。 Inside that loop, you'll look for distinct logins that have either started in that minute, or are still continuing in that minute. 在该循环内,您将查找在那一刻开始或在那一刻仍在继续的独特登录。 You will grab the Distinct() user_ids (so that one user logging in twice within 5 seconds still counts as 1 login) and you will add that distinct count to the list of int. 您将获取Distinct()user_ids(以便一个用户在5秒钟内两次登录的用户仍然算作1次登录),并将该不同的计数添加到int列表中。

At the end, you'll have a list of int that's as long as the number of minutes in between startTime and endTime, and that list can be called with Average() to see the average number of logins for each given minute. 最后,您将获得一个int列表,该列表与startTime和endTime之间的分钟数一样长,并且可以使用Average()调用该列表以查看每给定分钟的平均登录数。

The above solutions for querying based on discrete time intervals is good, I have used the same method in some of my own work applications. 上面基于离散时间间隔进行查询的解决方案很好,我在自己的一些工作应用程序中使用了相同的方法。

However, one thing to note is that the number of concurrent users only changes when a user logs in or out. 但是,要注意的一件事是,并发用户数仅在用户登录或注销时才更改。 Moreover, the number of concurrent users only increases when the user logs in (Sorry for obvious comment, but trying to make sure I have this clear in my own mind too). 此外,并发用户数仅在用户登录时才增加(很抱歉,您的评论很明显,但我想确保自己也清楚这一点)。 So it should be sufficient to create a LINQ query that goes over each user found by your initial search (with the range restriction), and checking how many users are logged in at each "login time", and taking the maximum number from this. 因此,创建一个遍历通过初始搜索找到的每个用户(具有范围限制)的LINQ查询就足够了,并检查每个“登录时间”登录了多少用户,并从中获取最大数量。 Actual LINQ below (The code below is in VB.Net, and using my own field names as that is what I had to test with, my apologies if this is a problem): 下面的实际LINQ(下面的代码在VB.Net中,使用我自己的字段名称,因为这是我必须测试的内容,如果出现问题,我深表歉意):

Firstly, to get a list of concurrent users at each login point we have: 首先,要获得每个登录点的并发用户列表,我们有:

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)

Alternatively, you can get the "hlxListItem" with the highest number to get max concurrent users: 或者,您可以获取具有最高编号的“ hlxListItem”来获取最大并发用户:

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()

So, finally just some notes on the above. 因此,最后只是上面的一些注释。 hlxListItem is just a simple object with a generic field, and a text field. hlxListItem只是具有通用字段和文本字段的简单对象。 The generic in this case holds the date (login time) and the text field holds the number of concurrent users. 在这种情况下,通用名称保留日期(登录时间),文本字段保留并发用户数。 If I have time, I can try to edit the above examples into C# and to using your field names, but I posted the above because I could confirm that it works. 如果有时间,我可以尝试将上面的示例编辑为C#并使用您的字段名称,但是我发布了上面的示例,因为我可以确认它可以正常工作。 Let me know if the above helps you out, or if you need any additional help. 让我知道以上内容是否对您有帮助,或者您是否需要其他帮助。

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

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