Domanda

Ho una domanda LINQ mappata con Entity Framework che sembra qualcosa di simile:

image = this.Context.ImageSet
                    .Where(n => n.ImageId == imageId)
                    .Where(n => n.Albums.IsPublic == true)
                    .Single();

Questo restituisce un singolo oggetto dell'immagine e funziona come previsto.

Tuttavia, questa query restituisce tutte le proprietà del mio tavolo immagine nel DB. In circostanze normali, questo sarebbe bene, ma queste immagini contengono un sacco di dati binari che richiede molto tempo per tornare.

In sostanza, in essa allo stato attuale la mia query LINQ sta facendo:

Select ImageId, Name, Data
From Images
...

Ma ho bisogno di una query che fa questo instread:

Select ImageId, Name
From Images
...

Si noti che voglio caricare tutto tranne il dati. (Posso ottenere questi dati su un secondo passaggio async)

È stato utile?

Soluzione

Purtroppo, se si utilizza LINQ to SQL, non esiste una soluzione ottimale.

Ci sono 3 possibilità:

  1. Si ritorna l'Ente, con il monitoraggio di contesto e tutti, in questo caso Immagine, con tutti i campi
  2. È possibile scegliere i campi e restituire un tipo anonimo
  3. È possibile scegliere i campi e restituire una classe personalizzata fortemente tipizzato, ma si perde il monitoraggio, se è ciò che vogliono.

Amo LINQ to SQL, ma questo è il modo in cui è.

La mia unica soluzione per voi sarebbe quella di ristrutturare il database, e spostare tutti i dati di grandi dimensioni in una tabella separata, e link ad esso da tavolo Immagine.

In questo modo quando il ritorno Immagine che ci si ritorni solo una chiave nel nuovo campo dataID, e quindi si potrebbe accedere ai dati più pesante quando e se avete bisogno.

applausi

Altri suggerimenti

Questo creerà una nuova immagine con solo quei campi impostati. Quando si torna a ottenere i dati per le immagini selezionate, io suggerirei di andare avanti e ottenere il pieno set di dati invece di cercare di fondersi con i dati id / nome esistente. I campi ID / Name sono presumibilmente piccolo rispetto ai dati e il codice sarà molto più semplice che cercare di fare l'unione. Inoltre, potrebbe non essere necessario in realtà costruire un oggetto Immagine, utilizzando un tipo anonimo potrebbe soddisfare i vostri scopi altrettanto bene.

image = this.Context.ImageSet
                    .Where(n => n.ImageId == imageId)
                    .Where(n => n.Albums.IsPublic == true)
                    .Select( n => new Image { ImageId = n.ImageId, Name = n.Name }
                    .Single();

[Se si usa Linq 2 SQL] All'interno del progettista DBML, c'è un'opzione per rendere ritardare-caricato colonne della tabella individuale. Imposta questo a true per il vostro grande campo binario. Poi, che i dati non viene caricato fino a quando non viene effettivamente utilizzato.

[Domanda per tutti voi: Qualcuno sa se i quadri di entità supportano ritardata caricati varbinary / di in MSVS 2010 varchar? ]

Soluzione # 2 (per strutture a entità o LINQ 2 SQL):

Creare una vista della tabella che include solo la chiave primaria e il varchar (max) / varbinary (max). Mappa che in EF.

All'interno della vostra Entity Framework progettista, eliminare il varbinary (max) / varchar (max) proprietà dalla definizione della tabella (lasciandolo definito solo nella vista). Questo dovrebbe escludere il campo dalle operazioni di lettura / scrittura a quel tavolo, anche se si potrebbe verificare che con il registratore.

In genere si accede ai dati attraverso la tabella che esclude il blob di dati. Quando è necessario il blob, si carica una riga dalla vista. Non sono sicuro se sarete in grado di scrivere alla vista, io non sono sicuro di come si farebbe scrive. Si può essere in grado di scrivere alla vista, o potrebbe essere necessario scrivere una stored procedure, oppure si può busto fuori un file DBML per una tabella.

Non si può farlo con LINQ , almeno per ora ...

L'approccio migliore che so è creare View per la tabella è necessario, senza grandi campi e utilizzare LINQ con quella View.

In alternativa è possibile utilizzare il select nuova nell'espressione di query ...

var image =
(
    from i in db.ImageSet
    where i.ImageId == imageId && i.Albums.IsPublic
    select new
    {
        ImageId = i.ImageId,
        Name = i.Name
    }
).Single()

Le espressioni di query LINQ in realtà vengono convertiti per l'espressione lambda al momento della compilazione, ma io prefair utilizzando l'espressione di query in genere perché lo trovo più leggibile e comprensibile.

Grazie )

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