我正在编写一项跟踪在线射击游戏统计数据的服务。客户端向服务器报告事件,然后将事件记录在SQL Server数据库中。服务器应生成从客户端报告汇总的游戏事件报告 - 事件声明的真实性基于报告它的客户端数量。
我有一个Linq-to-SQL查询,它根据发生的时间(7秒内)对来自不同客户端的事件报告进行分组。
Events
.Select(e =>
Events.Where(ev =>
// Same event type
ev.Discriminator == e.Discriminator &&
// Same match
ev.ServerIpAddress == e.ServerIpAddress &&
SqlMethods.DateDiffSecond(ev.MatchStartTime, e.MatchStartTime) < 30 &&
// Find nearby events
Math.Abs(ev.MatchTime.TotalSeconds - e.MatchTime.TotalSeconds) < 7 &&
// That are duplicate
ev.VictimTribesGuid == e.VictimTribesGuid &&
ev.KillerTribesGuid == e.KillerTribesGuid &&
ev.KillType == e.KillType &&
ev.Weapon == e.Weapon
)
)
返回以下内容:
事件按预期分组,但由于外部查询是&#34;按事件&#34;,组是重复的(请参阅前两行)。
有没有办法剥离这些重复的群组?
答案 0 :(得分:1)
GroupBy
似乎是适当的方法。但这并不像它看起来那么容易。这似乎是一个合理的操作:集群事件发生时。你只需要定义某种“平等”,这样你就可以将更多或更少相同的事件分组,不是吗?您在同一游戏中选择的平等定义是:相隔不到7秒。
但是有一个问题类似于我所描述的here。当3个事件a
,b
和c
出现在0s,5s和10s时,“7s规则”定义了以下“等值”:
a ≈ b
b ≈ c
但是a
和b
相隔10秒,所以
a !≈ c
在数学术语中,这意味着平等不是传递性的。这意味着您不能简单地将事件分组,因为它们相距不到7秒。
我认为你需要一种不同的方法。你应该开始计算游戏中第一次发生的事件。应计算此事件发生后7秒内发生的所有事件(在同一游戏中)。从7秒开始的第一个事件开始一个新的计数。这可以通过简单的foreach
完成。
一个复杂的问题是,我上面说的所有内容也适用于MatchStartTime
条件,您决定游戏是“平等的”。我认为你应该尝试找到一种不那么模糊的方法来建立这个事实,例如通过为游戏实例分配一个guid。否则你应该采取与事件“相等”相同的方法。
答案 1 :(得分:0)
尝试使用.Distinct();
Events
.Select(e =>
Events.Where(ev =>
// Same event type
ev.Discriminator == e.Discriminator &&
// Same match
ev.ServerIpAddress == e.ServerIpAddress &&
SqlMethods.DateDiffSecond(ev.MatchStartTime, e.MatchStartTime) < 30 &&
// Find nearby events
Math.Abs(ev.MatchTime.TotalSeconds - e.MatchTime.TotalSeconds) < 7 &&
// That are duplicate
ev.VictimTribesGuid == e.VictimTribesGuid &&
ev.KillerTribesGuid == e.KillerTribesGuid &&
ev.KillType == e.KillType &&
ev.Weapon == e.Weapon
).Distinct();
)