2010-04-28 41 views
15

Sto usando Linq per interrogare il mio database e restituire un IList generico.IEnumerable <> to IList <>

Qualsiasi cosa abbia provato, non è stato possibile convertire un IQueryable in un IList.

Ecco il mio codice.

Non riesco a scrivere più semplice di questo e non capisco perché non funzioni.

public IList<IRegion> GetRegionList(string countryCode) 
{ 
    var query = from c in Database.RegionDataSource 
       where (c.CountryCode == countryCode) 
       orderby c.Name 
       select new {c.RegionCode, c.RegionName}; 

    return query.Cast<IRegion>().ToList(); 
} 

Ciò restituisce un elenco con il giusto numero di elementi, ma sono tutti vuoti prega di aiuto, io sono bloqued con questo per un paio di giorni ormai

+1

Questa domanda e le risposte davvero illustrano il tema della tipizzazione anatra, e C#/limitazioni Linq –

risposta

16

La sua dichiarazione select restituisce un tipo anonimo: new {c.RegionCode, c.RegionName}

Questo non può essere convertito in IRegion - che sarebbe fondamentalmente Duck-tipizzazione, che C# non supporta.

L'istruzione linq deve restituire un tipo che implementa IRegion - quindi il codice dovrebbe funzionare.

Tuttavia non dovrebbe essere eseguito - lo Cast<IRegion> dovrebbe generare un'eccezione di runtime.

In sostanza:

// this isn't anonymous, and should cast 
public class MyRegion : IRegion { 
    public string RegionCode {get;set;} 
    public string RegionName {get;set;} 
} 

public IList<IRegion> GetRegionList(string countryCode) 
{ 
    var query = from c in Database.RegionDataSource 
       where (c.CountryCode == countryCode) 
       orderby c.Name 
       select new MyRegion {RegionCode = c.RegionCode, RegionName = c.RegionName}; 

    return query.Cast<IRegion>().ToList(); 
} 

Aggiornamento

Se il tipo di Linq sottostante implementa IRegion questo può essere molto più semplice:

public IList<IRegion> GetRegionList(string countryCode) 
{ 
    var query = 
     from region in Database.RegionDataSource 
     where region.CountryCode == countryCode 
     orderby region.Name 
     select region; 

    return query.ToList(); 
} 
+1

Non dovresti aver bisogno di 'Cast ()' ora che stai proiettando in un tipo concreto. –

+0

@cottsak: Sì, lui - 'IList ' è invariante. –

+0

Ho la mia regione di classe autogenerata Linq che implementa IRegion. Quando lo uso, ho ricevuto un altro messaggio di errore La costruzione esplicita del tipo di entità "xxxx.LinqToSql.xxxx.Region" nella query non è consentita. – nachid

5

Sono sorpreso non è solo non aver completamente - stai provando a trasmettere ogni risultato a uno IRegion, ma stai generando istanze di un tipo anonimo, che certamente non implementerà IRegion.

Avete un tipo di calcestruzzo che implementa IRegion?

+3

forse il numero giusto di elementi era 0 – Jimmy

2

Il cast di IRegion vinto' lavoro. Stai selezionando un tipo anonimo che non implementerà IRegion. C'è un modo per creare un'istanza di qualcosa che implementa IRegion?

1

Forse avete bisogno di qualcosa di simile:

public IList<IRegion> GetRegionList(string countryCode) 
{ 
    var query = from c in Database.RegionDataSource 
       where (c.CountryCode == countryCode) 
       orderby c.Name 
       select new Region() 
        { 
         RegionCode = c.RegionCode, 
         RegionName = c.RegionName 
        }; 

    return query.ToList(); 
} 
+0

ho bisogno in qualche modo di lanciare a IRegion prima di tornare la mia domanda Il compilatore si lamenta che non può convertire IList a IList nachid

+0

Skeet è corretto. È necessario il 'Fusioni ()' –

0

Forse avete bisogno di qualcosa di simile:

public IList<IRegion> GetRegionList(string countryCode) 
{ 
    var query = from c in Database.RegionDataSource 
       where (c.CountryCode == countryCode) 
       orderby c.Name 
       select new Region() 
        { 
         RegionCode = c.RegionCode, 
         RegionName = c.RegionName 
        }; 

    return query.ToList(); 
} 
+0

ho finito per fare questo pubblica IList GetRegionList (stringa countryCode) {var query = from c in Database.RegionDataSource dove (c.CountryCode == countryCode) orderby c.Name selezionare c; return query.Cast () .ToList(); } Tornerò presto qui e ti faccio sapere Grazie per il tuo prezioso aiuto – nachid

Problemi correlati