Utilizzando Linq per ObjectDataSource: come trasformare il datetime usando ToShortTimeString?

StackOverflow https://stackoverflow.com/questions/448890

  •  19-08-2019
  •  | 
  •  

Domanda

Sto accedendo a una business class usando un ObjectDataSource e sto provando a produrre un output sensato per l'utente. I valori di ritorno descrivono una classe (come in Classroom e insegnamento, non software). Vorrei mostrare l'orario della lezione in un intervallo come questo: " 9: 00-10: 00 " ;.

Questa è la query Linq che sto usando per estrarre i dati:

return classQuery.Select(p => new SelectClassData
                              {
                                   ClassID = p.ClassID,
                                   Title = p.Title,
                                   StartDate = p.StartDate.ToShortDateString(),
                                   EndDate = p.EndDate.ToShortDateString(),
                                   TimeOfClass =
                                   p.StartDate.ToShortTimeString() + " - " +
                                                       p.EndDate.ToShortTimeString()
                               }).ToList();

Come puoi vedere, codifico l'ora di inizio e di fine nelle date di inizio e di fine anche se queste potrebbero essere potenzialmente in date diverse.

Quando eseguo questo codice ottengo:

" Impossibile tradurre l'espressione 'p.EndDate.ToShortTimeString ()' in SQL e non può trattarla come un'espressione locale. "

So che sto proiettando i risultati ma, essendo nuovo a Linq, avevo supposto che la chiamata C # a ToShortTimeString fosse avvenuta dopo la proiezione. Qualcuno può aiutarmi a capire come ottenere la stringa che sto cercando?

È stato utile?

Soluzione

Il motivo è che la query viene utilizzata in LINQ to SQL. LINQ to SQL considera le query come alberi delle espressioni. Ha dei mapping definiti per alcuni metodi (ad esempio, Contains ) ma poiché non li esegue realmente, non può funzionare con metodi arbitrari. Analizza la query e la invia al server SQL. L'equivalente della query verrà eseguito come un'istruzione SQL sul server di database e il risultato tornerà. Il problema è ToShortTimeString () non ha una traduzione SQL equivalente in LINQ to SQL. Il trucco usato qui è quello di recuperare i dati dal server SQL e chiamare il metodo sul lato client ( AsEnumerable farà questo).

return classQuery.Select(p => new { p.ClassID, p.Title, p.StartDate, p.EndDate })
   .AsEnumerable()
   .Select(p => new SelectClassData { 
       ClassID = p.ClassID, 
       Title = p.Title, 
       StartDate = p.StartDate.ToShortDateString(), 
       EndDate = p.EndDate.ToShortDateString(), 
       TimeOfClass = p.StartDate.ToShortTimeString() + " - " + p.EndDate.ToShortTimeString() })
   .ToList();

Altri suggerimenti

Mi piace molto la risposta di Mehrdad. Non solo risolve il problema, mi insegna anche qualcosa su Linq. Grazie!

Tuttavia, ho continuato a risolvere il problema e ho escogitato un approccio diverso che descriverò qui nel caso in cui qualcun altro inciampare su questa domanda voglia prendere in considerazione. Il mio codice Linq to SQL ora recita:

return classQuery.Select(p => new SelectClassData
                              {
                                   ClassID = p.ClassID,
                                   Title = p.Title,
                                   sDate = p.StartDate,
                                   eDate = p.EndDate
                              }).ToList();

Nota che sDate ed eDate sono ora oggetti DateTime invece che stringhe. In " SelectClassData " oggetto, ho semplicemente cambiato la dichiarazione in modo che l'accesso alle variabili StartDate, EndDate e TimeOfClass passi attraverso un getter di proprietà:

public class SelectClassData
{
    public int ClassID { get; set; }
    public string Title { get; set; }
    public DateTime sDate { get; set; }
    public DateTime eDate { get; set; }
    public string StartDate { get { return GetSDate(); } }
    public string EndDate { get { return GetEDate(); } }
    public string TimeOfClass { get { return GetTimeOfClass(); } }

    protected string GetSDate()
    {
        return sDate.ToShortDateString();
    }

    protected string GetEDate()
    {
        return eDate.ToShortDateString();
    }

    protected string GetTimeOfClass()
    {
        return sDate.ToShortTimeString() + " - " + eDate.ToShortTimeString();
    }
}

Cioè, ho impostato sDate ed eDate tramite LinqToSql ma eseguo " ToShortTimeString " e " ToShortDateString " trasformazioni dopo il recupero di Linq implementandolo nella classe di dati di destinazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top