Domanda

Come si fa a lazy load elenchi nidificati, senza in realtà l'esecuzione della query?Utilizzando un esempio molto semplice, diciamo che ho:

class CityBlock {
     IList<Building> BuildingsOnBlock;
     Person BlockOwner;
}

class Building {
     IList<Floor> FloorsInBuilding;
}

class Floor {
     IList<Cubicle> EmployeeCubicles;
}

Class Cubicle {
     System.Guid CubicleID;
     Person CubicleOccupant;
}

E poi nel mio repository strato, ho il seguente metodo:

GetCityBlocks()

E poi il livello di Servizio dovrò GetCityBlocksByOwner, dove I utilizzare un metodo di estensione per ottenere i blocchi di città di proprietà di una persona specifica, dire che vogliamo solo Guido blocchi:

GetCityBlocks().ForOwner("Guido")

Se facciamo un .ToList() nel repository sta per eseguire le query - che sta per essere ridicolo dal momento che non sappiamo che i blocchi ci stiamo avvicinando a quel livello.Quindi la domanda è, come possiamo fare questo in modo efficace?

Supponiamo ci sono 50000 blocco proprietari, e alcune 1000000 isolati della città, il caricamento di tutti non è un'opzione.Utilizzando IQueryables non funziona a causa della nidificazione (senza estremi di hacking, almeno che io sappia).Inoltre, se provo a usare qualcosa come Rob Conery del LazyList, quindi abbiamo sostanzialmente una perdita dal nostro DAL nostro dominio modelli, che potrebbe essere molto molto male in futuro.

Allora, come faccio a farlo correttamente?

  • È una questione di determinazione del contesto corretto?Se è così, noi questo è il Repository di Livello, o il Livello di servizio?
  • Faccio la metà di fondere insieme il livello di Servizio e il mio Repository strato di ottenere molto specifici metodi di servizio?
  • O mi manca qualcosa di completamente diverso?(ancora relativamente nuovo per il Linq2Sql cosa, che è in fase di esaurimento comunque così...)

Edit: Nel modello di repository, attualmente stiamo mappatura per i nostri oggetti di dominio, in modo che sarebbe guardare qualcosa come questo:

public IQueryable<CityBlock> GetCityBlocks(){
    var results = from o in db.city_blocks
                  let buildings = GetBuildingsOnBlock(o.block_id)
                  select new CityBlock {
                      BuildingsOnBlock = buildings,
                      BlockOwner = o.block_owner
                  };
    return results;
}

Per questo lavoro, siamo andati a fare gli edifici ottenere un .ToList(), a meno che non facciamo che il campo effettivo nel CityBlock oggetto di un IQueryable - che non mi sembra proprio, perché sembra come se troppo potere essere concesso a chiunque accede al CityBlock.BuildingsOnBlock campo.È questo mapping per il nostro dominio oggetti di qualcosa dobbiamo fare, forse, fino al livello di servizio?

È stato utile?

Soluzione

Lo fai restituendo IQueryables invece di ILists.

ToList () fa sì che le query per eseguire immediatamente, perché una conversione deve essere eseguita da IQueryable a IList.

Fino a quando si sta tornando IQueryables lazy loading dovrebbe rinviare l'esecuzione fino a quando è effettivamente necessario i dati, vale a dire quando ToList () viene chiamato.

Non riesco a trovare un punto di riferimento in questo momento, ma è la mia comprensione che, se lo si fa in questo modo, LINQ to SQL ha la possibilità di ottimizzare l'SQL invia al server. In altre parole, in ultima analisi, di leggere questi record:

GetCityBlocks().ForOwner("Guido")

, piuttosto che questi record:

GetCityBlocks()

Altri suggerimenti

Si potrebbe provare un approccio diverso nella mappatura di oggetti di dominio per farlo funzionare.Il problema è che non importa quello che fai (a meno di non cambiare le liste per IQueryables a oggetti del dominio) si finisce ToList()ing mentre stai mappando.

L'altro modo di far linq2Sql fare la mappatura al tuo POCOs con la creazione di un custom datacontext e non utilizzando la finestra di progettazione per la mappatura :), in questo modo si mantiene il vostro modello di dominio pulita e lasciare linq2Sql popolano le dipendenze al momento giusto.Nota che in questo percorso ha i suoi problemi, ma può essere fatto.

Ecco un link per iniziare questo percorso

Il raggiungimento di POCO s in Linq to SQL

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