2013-05-14 16 views
5

Ho scritto una query LINQ per riempire un listview ma utilizza il metodo .ToString() che apparentemente non è consentito. Quando uso il codice qui sotto ricevo il seguente messaggio di errore:Utilizzo di ToString() nelle query LINQ?

Error: LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression

C'è un modo per utilizzare il ToString() in LINQ o se ciò non fosse possibile qual è la soluzione per la conversione di un DateTime alla stringa nella query . Si prega di nodo che ReleaseDateName è una stringa e ReleaseDate è un DateTime

using (var db = new ReleaseInfo()) 
{ 
    lvReleaseInfo.DataSource = (from r in db.MediaReleases 
           join rn in db.ReleaseNames 
           on new { MediaReleaseID = r.MediaReleaseID, CultureCodeID } equals new { rn.MediaReleaseID, rn.CultureCodeID } 
           join plat in db.MediaPlatforms 
           on new { MediaPlatformID = r.MediaPlatformID, CultureCodeID } equals new { plat.MediaPlatformID, plat.CultureCodeID } 
           join pub in db.MediaPublishers 
           on new { MediaPublisherID = r.MediaPublisherID, CultureCodeID } equals new { pub.MediaPublisherID, pub.CultureCodeID } 
           join c in db.Countries 
           on new { CountryID = r.CountryID, CultureCodeID } equals new { c.CountryID, c.CultureCodeID } 
           join rd in db.ReleaseDates 
           on new { MediaReleaseID = r.MediaReleaseID, CultureCodeID } equals new { rd.MediaReleaseID, rd.CultureCodeID } 
           join a in db.AffiliateLinks 
           on new { MediaReleaseID = r.MediaReleaseID, CultureCodeID } equals new { a.MediaReleaseID, a.CultureCodeID } 
           where r.SectionID == SectionID 
           select new 
           { 
            rn.ReleaseTitle, 
            plat.MediaPlatformName, 
            pub.MediaPublisherName, 
            c.CountryName, 
            ReleaseDate = (rd.ReleaseDate == null ? rd.ReleaseDateName : rd.ReleaseDate.ToString()), 
            a.AffiliateLinkAddress 
           }).ToList(); 
    lvReleaseInfo.DataBind(); 
} 

risposta

7

Dal momento che si sta materializzando la query per elencare in ogni caso, si potrebbe fare la conversione sul lato .NET, piuttosto che nel RDBMS, in questo modo:

... 
select new { 
    rn.ReleaseTitle, 
    plat.MediaPlatformName, 
    pub.MediaPublisherName, 
    c.CountryName, 
    rd.ReleaseDateName, 
    rd.ReleaseDate, 
    a.AffiliateLinkAddress 
}).AsEnumerable() // <<== This forces the following Select to operate in memory 
.Select(t => new { 
    t.ReleaseTitle, 
    t.MediaPlatformName, 
    t.MediaPublisherName, 
    t.CountryName, 
    ReleaseDate = t.ReleaseDateName ?? t.ReleaseDate.ToString() 
    t.AffiliateLinkAddress   
}).ToList(); 

Poiché la ToString() è chiamato ad un elemento dal IEnumerable<T>, non sarà più sicuro. Si noti inoltre l'uso dell'operatore ?? al posto di un condizionale con controllo nulla ? :.

+0

Sono nuovo di LINQ su Etityes, puoi spiegare come funziona la parte .Select? –

+2

@MatthewVerstraete '.Select' è solo sintassi del metodo. È lo stesso di quando si usa 'select' nella sintassi della query. 't => {...}' è un'espressione lambda. In pratica, per ogni elemento che selezioniamo facciamo praticamente ciò che è a destra dell'operatore '=>'. – evanmcdonnal

+0

Grazie, stavo anche pensando di convertirlo in un Proc sul server SQL dato che è un join abbastanza complesso. La conversione in un Proc mi consentirà anche di eseguire la logica sul lato di SQL Server. Ci sarebbe un aggiornamento delle prestazioni decente per andare proc vs il tuo metodo? –

0

Il problema è che non è possibile chiamare ToString() su un campo finché non è stato deserializzato. Quindi, piuttosto che provare a chiamare ToString() nella query, fallo semplicemente sui risultati in seguito.

Nel database il valore su cui si sta operando non ha la nozione di ToString() ed è per questo che si ottiene l'errore. La query può sembrare simile al codice C# ma tenere presente che sotto le copertine viene trasformato in una query SQL come qualsiasi altra. Dopo aver recuperato la lista, puoi scrivere una query LINQ molto semplice per risolvere il problema.