前段时间我问了SQL Server 的问题:如何使用带有 group by 的聚合函数来维护数据完整性?我在那里得到了很好的答案,但现在问题又出现了,这次是使用 Linq to SQL 而不是普通的 SQL。
背景故事:我有一个完整的 gps 数据表,如下所示:
GPS_id、user_id、纬度、经度、server_time、device_time
我使用以下 linq 查询来提取特定用户组的最新 gps 记录:
var query =
from gps in db.gps_data
where (from u in db.users
select u.user_id).Contains(gps.user_id)
group gps by gps.user_id into groupedGPS
select groupedGPS;
然后我像这样循环遍历它,但我必须先订购它才能正确获取“最新记录”。
foreach (var gpsItem in query) {
var ordered = gpsItem.OrderByDescending(g => g.device_time);
list.Add(ordered.First());
}
这给了我我需要的东西,但是在任何时候我都有 100 多个用户都有 500 多个 gps 记录(并且所有这些用户都以这种方式访问),所以这段代码需要 10 多秒,我认为这是不可接受的。
然后我将其更改为以下
var query =
from gps in db.gps_data
where (from u in db.users
select u.user_id).Contains(gps.user_id)
group gps by gps.user_id into groupedGPS
select new
{
GPS_id = groupedGPS.Max(x => x.GPS_id),
user_id = groupedGPS.Max(x => x.user_id),
latitude = groupedGPS.Max(x => x.latitude),
longitude = groupedGPS.Max(x => x.longitude),
server_time = groupedGPS.Max(x => x.server_time),
device_time = groupedGPS.Max(x => x.device_time)
};
这个查询确实看起来更快,因为据我了解,所有不必要的数据实际上从未加载到内存中。但是,就像几个月前我最初的问题一样,我已经以这种方式失去了数据完整性。不能保证我看到的是最新记录,只是分组中所有字段的最大值。这对大多数字段没有影响,但纬度和经度几乎总是不正确的,因为它们只是max()
在分组中找到的记录,而不是最近的记录。
我该如何解决这个问题?我意识到我有第一个解决方案来检索正确的数据,但是它花费的时间太长了。
谢谢您的帮助!