LINQ:根据最近的时间按选定的ID获取唯一行

问题描述 投票:1回答:1

我已经设法使用下面的当前语法并运行简单的LINQ查询来连接到数据库。我有一个数据库,其中包含大约20个唯一的SHIP_ID,每2分钟获取一次有关所有船舶位置的更新信息。这意味着SHIP_ID和TIMESTAMP组合在一起是唯一的,并且我的数据库中有很多数据,所以我希望负载在SQL Server上以返回正确的数据。而不是客户端要经过20k行的响应才能找到我想要的值。

我想检索数据库中存储的一组选定船只的最后位置,让我们说带有SHIP_ID的1、2和3的船只。到目前为止,SHIP_ID的位置存储在字符串[]中。

            using (var scope = _scopeFactory.CreateScope())
            {
                var dbContext = scope.ServiceProvider.GetRequiredService<AisRecordContext>();
                var query = dbContext.SimpleAisRecords
                    //LINQ statements goes here to get intended result
                    .Where ?
                    .GroupBy ?
                    .Select? 
                    .OrderderByDecending ?

            }

我如何继续进行正确的LINQ语句以获取所需的数据?我还希望结果具有它选择的整个行作为数据,例如,LAT,LON,SPEED和HEADING是我的其他一些列。

我也想知道返回结果的最佳格式是什么。结果将是返回的行,即我要调用的SHIP_ID所在的TIMESTAMP最新的行。我将需要数据库中的所有列(大约15列),因为我将在地图中显示数据。我会使用ToList吗? ToArray?或者以某种方式让我的查询成为结果,而无需在添加后对其进行修改。

感谢您的时间(对于一个非常具体的问题,我们深感抱歉,找不到任何文章将最新ID日期的行乘以选定的ID)

c# linq dbcontext
1个回答
0
投票

我假设您的SHIP_ID是int类型?如果是这样:

var ships = new string[]{ "1","2","3"};
using (var scope = _scopeFactory.CreateScope())
{
    var dbContext = scope.ServiceProvider.GetRequiredService<AisRecordContext>();
    var result = dbContext.SimpleAisRecords
        .Where(r => ships.Any(i => int.Parse(i) == r.SHIP_ID)) //Looks for any records matching any item in ships
        .OrderByDescending(r => r.TIMESTAMP); // Orders by time stamp descending...
}

[您可以选择最新的一个(这是自我们按时间戳排序以来的第一个),如下所示:var latestShip = result.FirstOrDefault();

关于要返回的集合类型,这取决于您在之后需要执行的操作...拥有原始记录可让您灵活地进行更新,如果需要,可以删除。

希望这有帮助吗?否则请澄清:)


0
投票

使这一点变得复杂的原因是,您想检索具有多艘船的最新时间戳的行。我认为唯一的方法是为每个SHIP_ID发出请求,并用每个结果填充一个列表。

var lastLocations = new List<SimpleAisRecords>();
var shipIds = new string[] { "1", "2", "3" };

using (var scope = _scopeFactory.CreateScope())
{
    var dbContext = scope.ServiceProvider.GetRequiredService<AisRecordContext>();
    foreach (var shipId in shipIds)
    {
        // Gets records for a SHIP_ID, orders by newest to oldest, and then grabs the first (newest) record
        var query = dbContext.SimpleAisRecords
                             .Where(ship => ship.SHIP_ID == shipId)
                             .OrderderByDecending(ship => ship.TIMESTAMP)
                             .FirstOrDefault();

        if (query != null)
        {
            lastLocations.Add(query);
        }
    }
}

默认情况下,它将返回关联表中的所有列,因此您将拥有LAT,LON,SPEED,HEADING以及所需的所有其他列。

© www.soinside.com 2019 - 2024. All rights reserved.