从 linq 查询中检索 DateTimeOffset 对

Retrieve DateTimeOffset pairs from linq query

这一定是要解的逻辑方程,但我看不懂解法。我有一个有效的例子。但是在现实世界中,我从 linq 查询中获取数据。如何从linq query接收数据来对应这个例子?

这是一个例子:

public List<GanttChartModel> GetActivites()
{
  var result = new List<GanttChartModel>();

  result.Add(new GanttChartModel { XAxisValue = "Design", YAxisValue = DateTimeOffset.Now.AddDays(-30) });
  result.Add(new GanttChartModel { XAxisValue = "Design", YAxisValue = DateTimeOffset.Now.AddDays(0) });

  result.Add(new GanttChartModel { XAxisValue = "Develop", YAxisValue = DateTimeOffset.Now.AddDays(-22) });
  result.Add(new GanttChartModel { XAxisValue = "Develop", YAxisValue = DateTimeOffset.Now.AddDays(-10) });

  result.Add(new GanttChartModel { XAxisValue = "Test", YAxisValue = DateTimeOffset.Now.AddDays(-14) });
  result.Add(new GanttChartModel { XAxisValue = "Test", YAxisValue = DateTimeOffset.Now.AddDays(-8) });

  return result;
}

这是我当前无法运行的 linq 查询:

  List<GanttChartModel> GanttChart = this.ProjectsList
  .Select(s => new GanttChartModel
  {
    XAxisValue = s.Name,
    YAxisValue = new DateTimeOffset(s.ProjectStartDate).AddDays((s.ProjectEndDate.Day - s.ProjectStartDate.Day)),
  }).ToList();

这是型号:

  public class GanttChartModel
  {
    public string XAxisValue { get; set; }
    public DateTimeOffset YAxisValue { get; set; }
  }

正如您在示例中所见,甘特图是在成对数据之间构建的。如何进行 linq 查询以输出数据对,其中第一个是开始日期,第二个是结束日期?

项目列表示例:

public List<Project> GetProjects()
{
  var result = new List<Project>();

  result.Add(new Project { ProjectId = Guid.NewGuid(), Name = "Project 1", ProjectStartDate = new DateTime(2022, 8, 15), ProjectEndDate = new DateTime(2022, 9, 15) });
  result.Add(new Project { ProjectId = Guid.NewGuid(), Name = "Project 2", ProjectStartDate = new DateTime(2022, 8, 22), ProjectEndDate = new DateTime(2022, 8, 25) });
  result.Add(new Project { ProjectId = Guid.NewGuid(), Name = "Project 3", ProjectStartDate = new DateTime(2022, 7, 25), ProjectEndDate = new DateTime(2022, 8, 2) });

  return result;
}

项目模型:

  public class Project
  {
    public Guid ProjectId { get; set }
    public string Name { get; set; }
    public DateTime ProjectStartDate { get; set; }
    public DateTime ProjectEndDate { get; set; }
  }

顺便说一下,这是 Blazor 中的 Apex 图表,但是问题是关于如何在 linq 中构建成对输出。

  <ApexChart TItem="GanttChartModel"
           Options=Options
           XAxisType="XAxisType.Datetime">
    <ApexRangeSeries TItem="GanttChartModel"
                   Items="this.GanttChart"
                   XValue="@(e => e.XAxisValue)"
                   YValue="@(e => e.YAxisValue.ToUnixTimeMilliseconds())" />
  </ApexChart>

我想你可以尝试使用ForEach来制作逆轴。

var result = new List<GanttChartModel>();
 this.ProjectsList.ForEach(r =>{
 result.Add(new GanttChartModel
            {
                XAxisValue = r.Name,
                YAxisValue = r.ProjectStartDate
            });
 result.Add(new GanttChartModel
            {
                XAxisValue = r.Name,
                YAxisValue = r.ProjectEndDate
            });
});

https://dotnetfiddle.net/1Dl8hm

您可以使用Enumerable.SelectMany来return多个结果,例如:

var results = this.ProjectsList
                  .SelectMany(s => new []{
                                      new GanttChartModel{
                                      {
                                          XAxisValue = s.Name,
                                          YAxisValue = s.ProjectStartDate
                                      },
                                      new GanttChartModel{
                                      {
                                          XAxisValue = s.Name,
                                          YAxisValue = s.ProjectEndDate
                                      }
                              });

results 是一个 IEnumerable<GanttChartModel>。您可以使用 ToList()ToArray().

等普通 LINQ 方法将其转换为数组、列表或字典

但要小心 - 转换 DateTimeKind 不是 UTCDateTime 会导致 local 偏移。如果您想将 DateTime 值视为 UTC,则必须明确指定偏移量:

var utc=TimeSpan.Zero;

var results = this.ProjectsList
                  .SelectMany(s => new []{
                      new GanttChartModel{
                      {
                          XAxisValue = s.Name,
                          YAxisValue =new DateTimeOffset( s.ProjectStartDate,utc);
                      },
                      new GanttChartModel{
                      {
                          XAxisValue = s.Name,
                          YAxisValue =new DateTimeOffset(s.ProjectEndDate, utc)
                      }
                    });