Verwenden Sie Linq, um den ersten und den letzten Wert auszuwählen

93439
Family

Ich möchte nur die ersten und letzten Werte in einem Datumsbereich erhalten. Ich habe folgenden Code:

  using (var myEntities = new dataEntities())
  {
      var myValues = (from values in myEntities.PointValues
                      where values.PointID == dataValue && values.DataTime >= fromDate && values.DataTime <= toDate
                      orderby values.DataTime
                      select new BarChartValue
                      {
                          Time = values.DataTime,
                          Value = values.DataValue
                      }).ToList();
      var myBarChart = new List<BarChartValue> { myValues.First(), myValues.Last() };
      return myBarChart;
  }

Dies erscheint mir ineffizient, da ich zunächst die gesamten Werte für den Datumsbereich auswähle. Ich kann anscheinend keinen Weg finden, den select-Befehl als erstes und letztes zu bezeichnen. Sicher muss es einen Weg geben, dies zu tun?

Als Antwort auf Svick.

Also, wenn ich das mache:

      var firstValue = (from values in myEntities.PointValues
                      where values.PointID == dataValue && values.DataTime >= fromDate && values.DataTime <= toDate
                      orderby values.DataTime
                      select new BarChartValue
                      {
                          Time = values.DataTime,
                          Value = values.DataValue
                      }).First();
      var lastValue = (from values in myEntities.PointValues
                        where values.PointID == dataValue && values.DataTime >= fromDate && values.DataTime <= toDate
                        orderby values.DataTime
                        select new BarChartValue
                        {
                            Time = values.DataTime,
                            Value = values.DataValue
                        }).Last();

Ist das der beste Weg, dies zu tun? Ich habe keine Werkzeuge für die Profilerstellung (oder ich bin mir nicht sicher, wie ich sie verwenden soll).

Die von svick bereitgestellte Lösung lautet:

      var myValues = (from values in myEntities.PointValues
                      where values.PointID == dataValue && values.DataTime >= fromDate && values.DataTime <= toDate
                      orderby values.DataTime
                      select new BarChartValue
                          {
                              Time = values.DataTime,
                              Value = values.DataValue
                          });
      var myBarChart = new List<BarChartValue> { myValues.First(), myValues.OrderByDescending(p => p.Time).First() };

Ein großer Teil davon ist auf mein mangelndes Verständnis des Unterschieds zwischen IQueryable, IEnumerable und List zurückzuführen. Hier ist eine gute Erklärung, die mir geholfen hat, ein bisschen mehr zu verstehen, was los ist:

https://stackoverflow.com/questions/4844660/differences-between-iqueryable-list-ienumerator

Antworten
7
Sieht aus, als ob Last () möglicherweise bereits implementiert wurde? http://msdn.microsoft.com/de-de/library/bb354927%28v=vs.100%29.aspx. Vermutlich hängt es jedoch von Ihrem Target-Framework ab. Wissen Sie als Frage, warum Sie das nicht verwenden konnten? dreza vor 7 Jahren 0

2 Antworten auf die Frage

4
svick

What you could do is to remove the ToList() from your query. This would change your code from making a single query that returns many values to two queries, each returning a single value.

Frage bearbeitet Family vor 7 Jahren 0
@Family Ja, außer dass du dich nicht wiederholen musst. Sie sollten weiterhin "myValues" (aber ohne "ToList ()") haben und einfach "myValues.First ()" und "myValues.Last ()" wie zuvor aufrufen. svick vor 7 Jahren 0
Just in case others have a similar problem. I couldn't use myValues.Last(), I had to use myValues.OrderByDescending(p => p.Time).First(); Family vor 7 Jahren 0
@svick eine Abfrage. Produziert First () auf der IQueryable-Schnittstelle SQL (wenn das die Datenbank ist) wie Select top 1 *? dreza vor 7 Jahren 0
@dreza Ja, genau das sollte es tun. svick vor 7 Jahren 0
0
Peter Kiss

Create the base query:

var myValues = (from values in myEntities.PointValues
                where values.PointID == dataValue && values.DataTime >= fromDate && values.DataTime <= toDate
                select new BarChartValue
                {
                    Time = values.DataTime,
                    Value = values.DataValue
                })

Then build up the first and last query:

var firstAndLast = myValues.OrderBy(x => values.DataTime).Take(1)
                    .Union(
                        myValues.OrderByDescending(x => values.DataTime).Take(1)
                    ).ToList();

This will result in one SQL query if the backend is an SQL database and will not recieve entites which are unnecessary (i think the Last() would download all entities).