为了账号安全,请及时绑定邮箱和手机立即绑定

如何编写 linq 查询以按时间戳排序

如何编写 linq 查询以按时间戳排序

C#
慕桂英546537 2022-01-15 15:39:46
我想通过按时间戳降序来保持对象列表的顺序。收到错误消息 - 无法将列表转换为字符串。模型的采样时间2018 年 12 月 9 日晚上 11:24:37 public ActionResult A() {     var model = new AssetTrackersViewModel();     model.AssetTrackers.Add(getAssetDetails_CH("e8", DateTime.Now.Date, DateTime.Now.Date));     model = model.AssetTrackers.OrderByDescending(x => DateTime.Parse(x.time));//error      return View(model); }班级 public class AssetTracker {    public AssetTracker()    {        latitude = new List<string>();        longitude = new List<string>();        time = new List<string>();    }    public string deviceid { get; set; }    public List<string> latitude { get; set; }    public List<string> longitude { get; set; }    public List<string> time { get; set; }               }public class AssetTrackersViewModel{    public AssetTrackersViewModel()    {        AssetTrackers = new List<AssetTracker>();    }        public List<AssetTracker> AssetTrackers { get; set; }}
查看完整描述

3 回答

?
RISEBY

TA贡献1856条经验 获得超5个赞

问题是您将时间存储为字符串和视图模型中的列表。取决于您要完成的任务:即查找具有最新时间的资产跟踪器:

  model = model.AssetTrackers
    .OrderByDescending(x => x.time
      .Select(t=>DateTime.Parse(t)).OrderByDescending(t=>t).First())
      .FirstOrDefault();

问题是您指示 Linq 将 DateTime.Parse 应用于一个List<string>而不是列表中的每个单独的字符串。

我建议将日期时间存储为 DateTime 而不是字符串,或者至少将它们存储在 ISO-8601 (YYYY-DD-MMTHH:mm:ss(Z)) 中,因为这可以进行比较和排序。

此外,如果您在这些资产跟踪器和时间之间存在一对多的关系,那么我建议您将实体中的关系与 DateTimes 进行映射。如果数据库正在存储 DateTime,请避免转换为字符串,即使您想在视图模型中格式化日期。让视图模型将格式化的日期作为属性公开,但允许代码使用 DateTime,因为您可以准确地对其进行排序和比较,而无需 DateTime.Parse 的额外成本。


查看完整回答
反对 回复 2022-01-15
?
largeQ

TA贡献2039条经验 获得超7个赞

首先,我不能强调这一点,将日期存储为字符串不是一个好主意。直接使用 DateTimes 即可。


您的AssetTracker对象有一个名为 的属性time。该属性是一个字符串列表。DateTime.Parse无法解析列表 - 它可以解析字符串。这就是您收到错误消息的原因。


从你的问题中你想做什么并不完全清楚。


您想按AssetTracker他们拥有的最高时间戳排序列表吗?


var trackersByHighestTimeDesc = 

   model.AssetTrackers

   .OrderByDescending(x => x.time.Select(DateTime.Parse).Max());

您是否要对每个时间戳列表进行排序,但保持资产跟踪器的顺序不变?


foreach(var at in model.AssetTrackers) {

    at.time = at.time.OrderByDescending(DateTime.Parse);

}


查看完整回答
反对 回复 2022-01-15
?
撒科打诨

TA贡献1934条经验 获得超2个赞

time是(并且不能是,这就是您收到错误的原因)的List<string>属性。您想如何根据每个项目的时间属性进行排序?换句话说,您想如何将一个时间列表与另一个时间列表进行比较以确定排序顺序?AssetTrackerDateTimeParseList<string>List<AssetTracker>

由于您正在比较 a 属性上的对象List<string>,因此您需要某种方法来确定该属性值的基线。我想到了两种方法:MinMax

  1. 从列表中获取每个对象的最大时间并将其用作比较:

    model.AssetTrackers = model.AssetTrackers    .OrderByDescending(x => x.time.Max(t => DateTime.Parse(t))).ToList();

  2. 从列表中获取每个对象的最短时间并将其用作比较:

    model.AssetTrackers = model.AssetTrackers    .OrderByDescending(x => x.time.Min(t => DateTime.Parse(t))).ToList();

我想,第三种选择是取平均值,这会有点不同,因为它需要数字类型,而不是日期。但幸运的是,我们可以使用Ticks属性进行比较:

  1. 从列表中获取每个对象的最短时间并将其用作比较:

    model.AssetTrackers = model.AssetTrackers    .OrderByDescending(x => x.time.Average(t => DateTime.Parse(t).Ticks)).ToList();

无论如何,如果您将属性存储为(最好是 UTC)DateTime对象而不是字符串,生活会简单得多。如果输入是沿线某处的字符串,最好预先排除任何解析错误,而不是在我们稍后尝试处理数据时。


查看完整回答
反对 回复 2022-01-15
  • 3 回答
  • 0 关注
  • 171 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信