Domanda

Ho sviluppato una webapp utilizzando Linq to NHibernate negli ultimi mesi, ma non hanno profilato il codice SQL che genera fino ad ora. Utilizzando NH Profiler, ora sembra che il seguente pezzo di codice colpisce il DB più di 3000 volte in cui viene eseguita l'espressione LINQ.

        var activeCaseList = from c in UserRepository.GetCasesByProjectManagerID(consultantId)
                             where c.CompletionDate == null
                             select new { c.PropertyID, c.Reference, c.Property.Address, DaysOld = DateTime.Now.Subtract(c.CreationDate).Days, JobValue = String.Format("£{0:0,0}", c.JobValue), c.CurrentStatus };

Quando il metodo Repository appare come:

    public IEnumerable<Case> GetCasesByProjectManagerID(int projectManagerId)
    {
        return from c in Session.Linq<Case>()
               where c.ProjectManagerID == projectManagerId
               select c;
    }

Sembra eseguire la query Repository iniziale prima, poi scorre tutti i risultati di controllo per vedere se la CompletionDate è nullo, ma l'emissione di un query per ottenere c.Property.Address prima.

Quindi, se la query iniziale restituisce 2.000 record, anche se solo cinque di loro non hanno CompletionDate, spara ancora fuori una query SQL per riportare i dettagli dell'indirizzo per i 2.000 record.

Il modo in cui mi ero immaginato questo dovrebbe funzionare, è che sarebbe valutare tutti WHERE e SELECT clausole e semplicemente amalgamare, quindi la query iniziale che sarebbe come:

SELECT ... WHERE ProjectManager = @ P1 e CompleteDate IS NOT NULL

Il che produrrebbe 5 record, e allora potrebbe sparare le ulteriori 5 domande per ottenere gli indirizzi. Sto aspettavo troppo qui, o sto semplicemente facendo qualcosa di sbagliato?

Anthony

È stato utile?

Soluzione

Cambiare la dichiarazione di GetCasesByProjectManagerID:

public IQueryable<Case> GetCasesByProjectManagerID(int projectManagerId)

Non è possibile comporre query con IEnumerable<T> - sono solo sequenze. IQueryable<T> è specificamente progettato per la composizione come questo.

Altri suggerimenti

Dal momento che non è possibile aggiungere un commento. Jon Skeet è giusto si vorrà usare IQueryable, questo è consente al provider Linq per costruire Pigramente SQL. IEnumerable è la versione ansioso.

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