Sto costruendo un'app utilizzando MVC 4 / Razor e EF 4 / .NET 4 in cui è possibile cercare elementi per codice di avviamento postale e recuperare così gli elementi solo a una certa distanza dal codice postale corrente. Ho una classe che calcola la distanza utilizzando i file del registro geografico (zip, lat e lon) e la formula di Haversine .
Il mio problema specifico riguarda la parte SQL del mio codice. Ho una vista che utilizza un cercapersone (20 risultati per pagina) e ha collegamenti ipertestuali che ordinano le colonne in ordine asc e desc. Ho anche 3 elenchi a discesa che possono ulteriormente filtrare i risultati in basso: Produttore, Categoria, Distanza.
Quando sto filtrando per dire 50 miglia, la mia classe recupera un IEnumerable di codici postali che si trovano all'interno della distanza richiesta. A volte questo può essere nell'area da 10.000 a 30.000. Ogni oggetto Item
contiene un int ZipCode
IlproblemacheEFgeneraquandoprovoadafferrareoggettidaldatabaseusandounelencodicodicipostaliaccettabilièUnadelletuequeryètroppoprofondamenteannidata.Provaaromperli.Presumochesiaperchénonpuoiavereunaclausolawhereconmigliaiadicondizioni.Questohasenso.Hotrovatouncollegamentoalcunigiornifachefondamentalmentesioccupavadicreareunatabellatemporaneadautilizzarecomeelenconellacondizionewhere,manonriescepiùatrovareillink.SiapplicavaanchearawADO.NETanzichéaEF.
Lamiadomandaèfondamentalmente,comepossoimplementarelafunzionalitàchedesiderosenzaapportaremodificheenormi?
using(varcontext=newJDMExchangeEntities()){varresults=context.Items.Include(P=>P.Manufacturer).Include(P=>P.Category).Include(P=>P.VehicleMake).Include(P=>P.VehicleModel).Include(P=>P.VehicleYear);//Categorylogicif(!string.IsNullOrEmpty(Categories)){results=results.Where(P=>P.Category.Name==Categories);}//Manufacturerslogicif(!string.IsNullOrEmpty(Manufacturers)){results=results.Where(P=>P.Manufacturer.Name==Manufacturers);}//Vehiclelogicif(Vehicle>0){results=results.Where(P=>P.YearId==Vehicle);}if(acceptableCodes.Count>0){List<int>codes=acceptableCodes.Keys.ToList();results=results.Where(P=>codes.Contains((int)P.ZipCode));//return_UoW.tblcoursebookingRepo.All//.Where(cb=>AttendanceIDs.Contains(cb.Attended))//.ToList();}////TakeoutitemsthatarenotintheManualQueryResultsDictionary//if(!String.IsNullOrEmpty(ManualQuery))//{//varall=listB.Where(b=>listA.Any(a=>a.code==b.code));//results=results.Where(r=>ManualQueryResults.Any(a=>a==r.id));//}////TakeoutzipsnotinthecloseCodesvariable//if(!string.IsNullOrEmpty(DistanceLimit))//{//results=results.Where(P=>closeCodes.Any(z=>z.ZipCode.Code==P.ZipCode));//}switch(sortOrder){case"Price_desc":
results = results.OrderByDescending(P => P.Price);
break;
case "Price":
results = results.OrderBy(P => P.Price);
break;
case "Date_asc":
results = results.OrderBy(P => P.PostDate);
break;
default:
results = results.OrderByDescending(P => P.PostDate);
break;
}
int pageSize = 20;
int pageNumber = (page ?? 1);
IPagedList<Item> cc = results.ToPagedList(pageNumber, pageSize);
Potrei chiamare .ToList()
da qualche parte prima di colpire il .ToPagedList()
, ma poi tornerò indietro di migliaia di voci e quindi ritarderò il tempo di risposta di alcuni secondi.
Dopo ho potuto facilmente creare un elenco a pagine dall'elenco IEnumerable. Voglio provare a ridurre al minimo i tempi di risposta e quindi penso che l'area che devo correggere sia nel codice SQL in modo da non estrarre dati non necessari e quindi filtrarli.