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

时间:2018-09-12 21:12:22

标签: c# linq

enter image description here我想通过降低时间戳来保持对象列表的顺序。错误提示-无法将列表转换为字符串。

从模型中采样时间

  

2018/12/09下午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; }
}

4 个答案:

答案 0 :(得分:2)

问题是您将时间存储为字符串并存储在视图模型的列表中。根据您要完成的任务: 即查找最近时间的资产跟踪器:

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

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

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

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

答案 1 :(得分:0)

timeList<string>的{​​{1}}属性(而AssetTracker不能DateTimeParse,这就是为什么出现错误)。您想如何根据各项的时间属性对List<string>进行排序?换句话说,您如何将一个时间列表与另一个时间列表进行比较以确定排序顺序?

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

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

    Max

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

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

我想,第三个选择是取平均值,这将有所不同,因为它需要数字类型而不是日期。但幸运的是,我们可以使用model.AssetTrackers = model.AssetTrackers .OrderByDescending(x => x.time.Min(t => DateTime.Parse(t))).ToList();属性进行比较:

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

    Ticks

在任何情况下,如果将属性存储为(最好是UTC)model.AssetTrackers = model.AssetTrackers .OrderByDescending(x => x.time.Average(t => DateTime.Parse(t).Ticks)).ToList();对象而不是字符串,则生活会简单得多。如果输入是行中某处的字符串,则最好先解决所有解析错误,而不是在稍后尝试处理数据时。

答案 2 :(得分:0)

首先,我对此不太强调,将日期存储为字符串不是一个好主意。只需直接使用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);
}

答案 3 :(得分:-1)

您要排序什么?因为您是按“列表时间”对AssetTrackers排序,还是要对“时间列表”进行排序?

如果您想对AssetTracker进行排序,请按时查看最小值,最大值,平均数。