使用LINQ选择具有唯一列值的所有行

6

我有一个包含4个字段的数据库,看起来像这样:

ID      DeviceId       Location        Date
1           A             ...            2
2           A             ...            1
3           B             ...            2

对于每个DeviceId,我想要最高日期记录中的位置。我可以按以下方式获取不同的DeviceId

// get all locations
var locations = Session.Query<Location>().ToList();

//Get the latest used unique deviceId's
var distinctDeviceIdsByDate = (
      from loc in locations
      orderby loc.DeviceId, loc.Date descending
      select loc.DeviceId).Distinct().ToList();

我会使用join来获取所需的行,但这没有任何用处,因为我除了DeviceId之外什么都得不到,因此无法确定要选择哪些行。如果我尝试选择以下内容:

select loc

我只能获取每一列的唯一组合行。我相信有一个简单的解决方案,但是现在我无法想出来。


2
那么对于每个设备ID,您想要来自具有最高日期记录的位置? - D Stanley
没错!我会编辑问题,让它表达你所说的内容。 - dansv130
你不应该编辑问题来包含答案;你应该标记你认为正确或对你最有帮助的答案。 - rae1
3个回答

7

我猜你需要使用GroupByTake的组合。试试这个:

var distinctDeviceIdsByDate = 
    locations.OrderByDescending(location => location.DeviceId)
             .ThenByDescending(location => location.Date)
             .GroupBy(location => location.DeviceId)
             .SelectMany(location => location.Take(1));

看起来这个方法符合我的要求!我会更新问题,并注明你的解决方案,给予你认可! - dansv130

1
假设每个DeviceIdDate是唯一的,您可以尝试
//Get the latest used unique deviceId's
var distinctDeviceIdsByDate = (
      from loc in Session.Query<Location>()
      group loc by loc.DeviceId
      into g
      select new
      {
          DeviceID = g.Key,  
          Location = g.OrderByDescending(l => l.Date).First().Location;
      };

这也看起来像是一个可能的解决方案,但由于DotNetWala的答案可行,我现在会使用它,并在今后遇到问题时调查其他解决方案。 - dansv130
这个在NHibernate中不起作用,会抛出以下SqlException错误:列“Location.Date”无效,因为它没有包含在聚合函数或GROUP BY子句中。 - CB-Dan

0

你可以使用分组来解决这个问题。

var locations = new [] {
    new { DeviceId = "A", Date = 2, Location = ".." },
    new { DeviceId = "A", Date = 1, Location = ".." },
    new { DeviceId = "B", Date = 2, Location = "...." },
};

var lastUsedLocations = 
    from l in locations
    group l by l.DeviceId into g
    let lastUsed = g.OrderBy(x => x.Date).Last()
    select lastUsed;

// lastUsedLocations contains
// DeviceId       Date        Location
// A              2           ..
// B              2           ....

这似乎也是一个可能的解决方案,但由于DotNetWala的答案有效,我现在会使用它,并在今后遇到问题时调查其他解决方案。 - dansv130
它们本质上是相同的。关键概念是分组。 - Mikael Östberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接