c# log Come trovare la data più vicina



entity framework iqueryable get sql (2)

Ho il grafico con tre precisioni.

Per ora, per 30 minuti, per 15 minuti.

La tabella con i miei dati è simile alla seguente:

Quando genero il mio grafico, partendo dall'ora speciale, ad esempio dall'ora corrente

Per esempio. Quando inizio dalle 18:00 e la mia precisione è per 15 minuti ho bisogno di dati da questi tempi

  • 18:00
  • 17:45
  • 17:30
  • 17:15
  • 17:00
  • ...

Nella mia tabella dati ho i dati massimi per 3 minuti, quindi quando vorrei ottenere i dati da 17:15 la mia query lambda restituisce null perché ho dati solo da 17:13 e 17:16.

Quindi ho bisogno della query che restituisce i dati più vicini ai miei dati. Nell'esempio superiore è necessario restituire i dati dalle 17:16.

Provo il Metodo DiffHours ma non funziona su MySQL. Ho bisogno di metodi per lavorare su MySQL e MSSQL

Il mio metodo attuale assomiglia a questo:

var report = _reportRepository.FindBy(a => a.Fridge.FridgeIdentity == fridgeIdentity && a.CreatedDate.Year == fromTime.Year && a.CreatedDate.Month == fromTime.Month && a.CreatedDate.Day == fromTime.Day && a.CreatedDate.Hour == fromTime.Hour).FirstOrDefault();

ma funziona solo per precisione all'ora.

Grazie per l'aiuto!


Answer #1

Che ne dici di questo, per ottenere il tempo più vicino a un intervallo particolare:

var fromTime = new DateTime(2016, 05, 20, 9, 0, 0);
var report = _reportRepository
             .OrderBy(m =>m.CreatedDate > fromTime 
                             ? m.CreatedDate - fromTime 
                             : fromTime - m.CreatedDate)
             .Take(1);

Answer #2

Hai mostrato solo un codice limitato e non erano del tutto specifici su alcuni punti anche dopo diverse domande a riguardo, quindi assumerò quanto segue:

  • sei in grado di creare un rapporto di lavoro con precisione oraria, ciò significa che puoi generare l'elenco degli orari desiderati, ad esempio 18:00, 18:15, 18:30 per un intervallo di 15 minuti (non puoi ottenere il dati corretti per esso) e questi tempi sono nella variabile da fromTime

  • hai sempre orari di arrotondamento come orari dei rapporti, quindi ad es. 18:00, mai 17:48

  • le voci più vicine possono essere sia prima che dopo il tempo di interrogazione

  • se si fa ad es. un rapporto di 15 minuti e non vi è alcun valore nel proprio database con un tempo di consegna tra le 17:45:00 e le 18:14:59, il rapporto non avrà alcun risultato per le 18:00 (poiché i dati coprono ogni 3 minuti, non dovrebbe essere un problema comunque, tranne che per le pause)

Devi utilizzare query diverse per i 3 intervalli di tempo. Per 15 minuti usa (assumendo che il tuo tavolo sia chiamato a ):

select *
from
(select *,
 convert(timestamp(date(date_add(CreatedDate, INTERVAL '7:30' MINUTE_SECOND)), 
         maketime(hour(date_add(CreatedDate, INTERVAL '7:30' MINUTE_SECOND)), 
         round(minute(date_add(CreatedDate, INTERVAL '7:30' MINUTE_SECOND)) div 15) 
          * 15, 0)), datetime) as filtertime
 from a
) as withfilter
order by filtertime, abs(timediff(filtertime, CreatedDate)) ;

Per gli altri intervalli, è necessario sostituire l'intervallo di conseguenza (quindi sostituire 7:30 della metà dell'intervallo in minuti e 15 dell'intervallo in minuti, quindi per un intervallo di 30 minuti sarebbe:

select *
from
(select *,
 convert(timestamp(date(date_add(CreatedDate, INTERVAL '15:00' MINUTE_SECOND)), 
         maketime(hour(date_add(CreatedDate, INTERVAL '15:00' MINUTE_SECOND)), 
         round(minute(date_add(CreatedDate, INTERVAL '15:00' MINUTE_SECOND)) div 30) 
          * 30, 0)), datetime) as filtertime
 from a
) as withfilter
order by filtertime, abs(timediff(filtertime, CreatedDate)) ;

(e 30:00 e 60 per l'intervallo orario).

Questo fondamentalmente arrotonda il tuo CreatedDate all'intero 15/30/60 minuti più vicino e lo ordini in base alla differenza temporale. CreatedDate sempre, quindi un CreatedDate 2016-05-20 09:15:00 verrà arrotondato al 2016-05-20 09:30:00 per un intervallo di 30 minuti, non per il 2016-05-20 09:00:00 alle 2016-05-20 09:00:00 .

Potresti voler dare un'occhiata diretta al risultato per capire la visione finale; per i tuoi dati di esempio, ad es. 2016-05-20 09:18:40 , per prima cosa calcolerà i 2016-05-20 09:15:00 , 2016-05-20 09:30:00 e 2016-05-20 09:00:00 per le 3 domande 15 minuti, 30 minuti e 1 ora. Quindi ordinerà in base alla loro distanza da questi orari (3: 40min, 11: 20min e 18: 40min).

Il tuo reportfilter dovrà utilizzare il tempo di CreatedDate invece del tempo di CreatedDate e dovrai aggiungere i minuti da confrontare a fromtime :

var report = _reportRepository.FindBy(a => a.Fridge.FridgeIdentity == fridgeIdentity 
   && a.filtertime.Year == fromTime.Year 
   && a.filtertime.Month == fromTime.Month 
   && a.filtertime.Day == fromTime.Day 
   && a.filtertime.Hour == fromTime.Hour
   && a.filtertime.Minute == fromTime.Minute).FirstOrDefault();




entity-framework-6