0

这是我想要做的:我的 ASP.NET Web API 接受来自客户端的图表“id”、“startTimestamp”和“endTimestamp”。我需要 Web API 仅选择 startTimestamp 和 endTimestamp 定义的时间戳范围内的“MeasureData”(请参阅​​随附的 EF5 概念模型图)。我的 Web API 向客户端返回一个 JSON AmSerialChart 对象图。然后我解析 JSON 对象图并使用 amCharts Javascript API 构建图表。该图表仅显示 startTimestamp 和 endTimestamp 之间的数据。

我不知道如何在我的控制器中编写一个 LINQ 表达式来过滤 MeasureData 并返回一个带有过滤后的 MeasureData 的 AmSerialChart 对象。

这是一次失败的尝试:

AmSerialChart amserialchart =
(AmSerialChart)db.AmSerialCharts
.Find(id)
.Graphs
.Select(g => g.Measure)
.SelectMany(m => m.MeasureData)
.Where(md => md.Timestamp >= startDate && md.Timestamp <= endDate);

“db.AmSerialCharts.Find(id)”找到合适的图表实体,但我不确定如何浏览对象图的其余部分以到达 MeasureData 过滤器。

4

2 回答 2

1

有时单行 LINQ 并不是解决问题的最佳方案。即使有可能,可读性通常也会消失。有时最好手动完成这项工作。

您的请求的问题是您希望AmSerialChart修剪具有完整对象层次结构的对象以匹配您的时间范围。问题是基本Select不会那样做。它将想要生成一个新列表或新对象。

我认为您最好的解决方案是“复制”您的对象层次结构,而不是尝试对其进行 LINQ:

var fullChart = charts.Where(c => c.Id == id).Single();
var result = new AmSerialChart()
{
  Id = fullChart.Id,
  Name = fullChart.Name,
  Description = fullChart.Description,
  FirstTimestamp = fullChart.FirstTimestamp,
  LastTimestamp = fullChart.LastTimestamp,
  Graphs = new List<Graph>()
};

foreach (var graph in fullChart.Graphs)
{
  var measure = graph.Measure;

  var newMeasure = new Measure()
  {
    Id = measure.Id,
    // Copy the rest of data

    MeasureData = new List<MeasureData>()
  };

  foreach (var measureData in measure.MeasureData)
  {
    if (measureData.Timestamp >= startDate && measureData.Timestamp <= endDate)
    {
      var newMeasureData = new MeasureData()
      {
        Id = measureData.Id,
        // Copy the rest of data
      };
      newMeasure.MeasureData.Add(newMeasureData);
    }
  }

  if (newMeasure.MeasureData.Count() > 0)
  {
    var newGraph = new Graph()
    {
      Id = graph.Id,
      // Copy the rest of data

      Measure = newMeasure
    };
    result.Graphs.Add(newGraph);
  }
}
于 2013-06-05T18:30:29.723 回答
1

过滤 MeasureData 并返回一个 AmSerialChart 对象

你最好使用Any()

var measureData = charts.Where(c => c.Id == id
     && c.Graphs.Any(g => g.Measure.MeasureData
    .Any(md => md.Timestamp >= startDate && md.Timestamp <= endDate)))
    .FirstOrDefault();

或者SingleOrDefault()如果预计不超过 1 个匹配项。

于 2013-06-05T21:05:04.117 回答