ciao,
vailfox ha scritto:
Sarà colpa della prima compilazione at runtime di asp.net??
Può darsi che la tua applicazione necessiti di qualcosa che alla prima esecuzione non è stato ancora inizializzato. Dalla seconda richiesta in poi questa risorsa è disponibile e il funzionamento è quello corretto.
Comunque, congetture a parte, dovresti usare il Sql Profiler per esaminare le query SQL che la tua applicazione invia al database. Da lì puoi capire se le query che il provider di Entity Framework sono quelle che ti aspetti.
A proposito dei cicli for annidati... non li usare. Entity Framework, offrendoti un modello ad oggetti, ti può dare l'illusione che il modello relazionale dei database sia storia passata ma non è così: EF deve comunque assemblare delle query SQL e se il codice che scrivi non tiene conto di questo fatto puoi ritrovarti con un'applicazione che soffre di prestazioni basse ed effetti collaterali indesiderati.
Nel caso specifico, i cicli for annidati costringeranno EF ad inviare al database più query di quante ne siano necessarie. Questo è un problema noto come
select n+1.
Ancora una volta, usa il Sql Profiler per renderti conto del dialogo che avviene tra l'applicazione e il database. Solo così puoi renderti conto di eventuali problemi e porvi rimedio.
La soluzione consiste nel riscrivere tutto il blocco di codice della funzione GetAllSuccessCustomer affinché usi una query LINQ.
Qui trovi un articolo di Stefano Mostarda per iniziare.
http://www.linqitalia.com/articoli/linq/introduzione-query-linq.aspxSe ho capito quel che devi realizzare, si tratta di selezionare i Customer che abbiano ogni loro Device su Ack = False e CurrentStatus.StatusEnum = EnumDeviceStatus.Successful. Questo include anche quei Customer che non hanno alcun Device.
A proposito della condizione che coinvolge StatusEnum: EF ancora non supporta le enumerazioni quindi immagino che quella sia un wrapper per una proprietà numerica chiamata Status (sbaglio?).
Per ottenere migliori prestazioni, conviene comunque rinunciare all'uso dell'enumerazione e scrivere una query LINQ simile a questa (provala e vedi se funziona...)
Public Function GetAllSuccessCustomer() As List(Of Customer)
Dim query = From c In _ctx.Customers.Include("Device")
Where c.Device.All(Function(d) d.Ack = False And d.CurrentStatus.Status <> 0)
Return query.ToList()
End Function
Per prima cosa, con l'extension method .Include dichiaro di voler usare la collezione Device correlata ai Customers. EF raccoglierà questo suggerimento (chiamato
eager loading) e nel creare una query SQL effettuerà una JOIN tra le tabelle di Customer e Device.
L'extension method .All, invece, impone che tutti gli elementi della sequenza Device verifichino le due condizioni fornite.
ciao
Modificato da BrightSoul il 16 aprile 2012 22.51 -